diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index d4d6fe8..6b36be5 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -15,6 +15,6 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: 18.x + node-version: 20.x cache: 'npm' - run: npm install && npm run prettier-check && npm run build diff --git a/.gitignore b/.gitignore index b733034..cfee3ce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ .vitepress/cache .vitepress/dist +.DS_Store + +node_modules \ No newline at end of file diff --git a/.vitepress/config.mts b/.vitepress/config.mts index 0a3ce5d..d671640 100644 --- a/.vitepress/config.mts +++ b/.vitepress/config.mts @@ -1,83 +1,103 @@ -import { defineConfig } from 'vitepress' +import { defineConfig } from "vitepress"; // https://vitepress.dev/reference/site-config export default defineConfig({ title: "Protomaps Docs", + head: [ + ["link", { rel: "icon", type: "image/png", href: "/favicon.png" }], + ["link", { rel: "apple-touch-icon", type: "image/jpg", href:"https://protomaps.com//apple-touch-icon.jpg" }], + ["meta", { property: "og:image", content: "https://protomaps.com/docs_opengraph.jpg" }] + ], description: "Technical Documentation for Protomaps", cleanUrls: true, + markdown: { + theme: { + light: 'github-light-high-contrast', + dark: 'github-dark-high-contrast' + } + }, themeConfig: { - logo: '/logo.svg', + logo: "/logo.svg", // https://vitepress.dev/reference/default-theme-config nav: [ - { text: 'Guides', link: '/' }, - { text: 'protomaps.com', link: 'https://protomaps.com/' }, - { text: 'Sponsor on GitHub', link: 'https://github.com/sponsors/protomaps' } + { text: "Guides", link: "/" }, + { text: "protomaps.com", link: "https://protomaps.com/" }, + { + text: "Sponsor on GitHub", + link: "https://github.com/sponsors/protomaps", + }, ], sidebar: [ { - text: 'Introduction', + text: "Introduction", collapsed: true, items: [ - { text: 'What is Protomaps?', link: '/' }, - { text: 'Getting Started', link: '/guide/getting-started' } - ] + { text: "What is Protomaps?", link: "/" }, + { text: "Getting Started", link: "/guide/getting-started" }, + { text: "Security and Privacy", link: "/guide/security-privacy" }, + ], }, { - text: 'PMTiles', + text: "PMTiles", collapsed: true, items: [ - { text: 'Concepts', link: '/pmtiles/' }, - { text: 'Creating PMTiles', link: '/pmtiles/create' }, - { text: 'Cloud Storage', link: '/pmtiles/cloud-storage' }, - { text: 'pmtiles CLI', link: '/pmtiles/cli' } - ] + { text: "Concepts", link: "/pmtiles/" }, + { text: "Creating PMTiles", link: "/pmtiles/create" }, + { text: "Cloud Storage", link: "/pmtiles/cloud-storage" }, + { text: "pmtiles CLI", link: "/pmtiles/cli" }, + ], }, { - text: 'PMTiles in the browser', + text: "PMTiles in the browser", collapsed: true, items: [ - { text: 'MapLibre GL', link: '/pmtiles/maplibre' }, - { text: 'Leaflet', link: '/pmtiles/leaflet' }, - { text: 'OpenLayers', link: '/pmtiles/openlayers' }, - ] + { text: "MapLibre GL", link: "/pmtiles/maplibre" }, + { text: "Leaflet", link: "/pmtiles/leaflet" }, + { text: "OpenLayers", link: "/pmtiles/openlayers" }, + ], }, { - text: 'Accelerating PMTiles', + text: "Accelerating PMTiles", collapsed: true, items: [ - { text: 'Overview', link: '/deploy/' }, - { text: 'AWS', link: '/deploy/aws' }, - { text: 'Cloudflare', link: '/deploy/cloudflare' }, - { text: 'Server (Caddy)', link: '/deploy/server' } - ] + { text: "Overview", link: "/deploy/" }, + { text: "Cost Calculator", link: "/deploy/cost" }, + { text: "AWS", link: "/deploy/aws" }, + { text: "Cloudflare", link: "/deploy/cloudflare" }, + { text: "Google Cloud", link: "/deploy/google-cloud" }, + { text: "Azure", link: "/deploy/azure" }, + { text: "Server", link: "/deploy/server" }, + ], }, { - text: 'OSM Basemaps', + text: "OSM Basemaps", collapsed: true, items: [ - { text: 'Downloads', link: '/basemaps/downloads' }, - { text: 'Basemap Layers', link: '/basemaps/layers' }, - { text: 'Basemap Styles', link: '/basemaps/styles' }, - { text: 'MapLibre GL', link: '/basemaps/maplibre' }, - { text: 'Leaflet', link: '/basemaps/leaflet' }, - { text: 'OpenLayers', link: '/basemaps/openlayers' } - ] - } + { text: "Downloads", link: "/basemaps/downloads" }, + { text: "Basemap Layers", link: "/basemaps/layers" }, + { text: "Basemap Flavors", link: "/basemaps/flavors" }, + { text: "Basemap Localization", link: "/basemaps/localization" }, + { text: "Building Tiles", link: "/basemaps/build" }, + { text: "MapLibre GL", link: "/basemaps/maplibre" }, + { text: "Leaflet", link: "/basemaps/leaflet" }, + ], + }, ], socialLinks: [ - { icon: 'github', link: 'https://github.com/protomaps' }, - { icon: 'mastodon', link: 'https://mapstodon.space/@protomaps' }, - { icon: 'twitter', link: 'https://twitter.com/protomaps' }, + { icon: "github", link: "https://github.com/protomaps" }, + { icon: "mastodon", link: "https://mapstodon.space/@protomaps" }, + { icon: "bluesky", link: "https://bsky.app/profile/protomaps.com" }, ], search: { - provider: 'local' + provider: "local", }, footer: { - message: 'An open source mapping system released under the BSD and ODbL licenses.', - copyright: '© 2019-present Protomaps LLC' - } - } -}) + message: + "An open source mapping system released under the BSD and ODbL licenses.", + copyright: "© 2019-present Protomaps LLC", + }, + }, +}); diff --git a/basemaps/build.md b/basemaps/build.md new file mode 100644 index 0000000..50d3a2c --- /dev/null +++ b/basemaps/build.md @@ -0,0 +1,64 @@ +# Building a custom basemap + +The Protomaps Basemap based on OpenStreetMap data is provided as a [free daily planet build](/basemaps/downloads), which can be downloaded in full, or extracted into sub-pyramids for certain areas. + +The pipeline to generate this daily basemap [is open source](https://github.com/protomaps/basemaps/tree/main/tiles) and based on the [Planetiler](https://github.com/onthegomap/planetiler) Java tiling engine. It can be run for your local city or country in minutes, or in about two hours for the planet on a high-end desktop or server. + +Advantages to generating basemaps yourself include: + +* **Data** - Build tiles from specific OpenStreetMap snapshots, such as up-to-the-minute data from [SliceOSM](https://slice.openstreetmap.us). +* **Customization** - modify the Java code to include custom tags. +* **Clipping** - build a custom, focused area map. Extracting an area from the daily planet build will include extra data in low zoom tiles, like in the below illustration: + +![extract vs clip](./extract_vs_clip.png) + +## Build a local map + +To start you will need: + +* a [Java Runtime Environment version 21+](https://github.com/onthegomap/planetiler/blob/main/CONTRIBUTING.md) and [Maven](https://maven.apache.org/install.html) installed. + +* An OpenStreetMap extract that covers your area of interest, such as an on-demand download from [SliceOSM](https://slice.openstreetmap.us) or a pre-generated download from [Geofabrik Downloads](https://download.geofabrik.de). + +* A GeoJSON administrative boundary for Łódź, Poland downloaded from the [Who's On First Spelunker](https://spelunker.whosonfirst.org/id/101913783). [Link to lodz.geojson](https://spelunker.whosonfirst.org/id/101913783/geojson) + +### Generate the map + +1. Create a checkout of the `basemaps` project and build the JAR. + +```sh +git clone https://github.com/protomaps/basemaps +cd basemaps/tiles +mvn clean package +``` + +2. Place your input OSM data into `data/sources` and run the tile generation JAR: + +```sh +cp my_area.osm.pbf data/sources/my_area.osm.pbf +java -jar target/protomaps-basemap-HEAD-with-deps.jar --clip=lodz.geojson --area=my_area --download +``` + +This will also download resources such as pre-processed OSM water and land polygons, [Natural Earth](https://naturalearthdata.com), and datasets for language support and ranking. + +3. Drag-and-drop your output `.pmtiles` to the [Basemaps Viewer at maps.protomaps.com](https://maps.protomaps.com): + +![extract vs clip](./lodz_viewer.png) + +## Build the planet + +The recommended system requirements for building a planet tileset in < 3 hours are: + +* CPU: As many CPU cores as possible. Recommended: Intel Core i9 series, AMD Ryzen 9 series, AWS `c7gd.8xlarge` or equivalent. +* RAM: 64GB of RAM. +* Storage: At least 1TB of NVMe SSD storage, or attached instance store on a VPS (not network-attached storage) + +Building the planet works the same way as before, but provide a Planet file from [planet.openstreetmap.org](http://planet.openstreetmap.org) as the `--area` argument, or `--osm_file` with a complete path and `--bounds=planet`. + +```sh +java -Xmx20g -jar target/protomaps-basemap-HEAD-with-deps.jar --nodemap-type=array --osm_path=/data/planet-latest.osm.pbf --output=/data/planet.pmtiles --bounds=planet --tmpdir=/var/scratch +``` + +* `-Xmx20g`: Give the Java runtime environment 20GB of heap space. +* `--nodemap-type=array`: a build option best for planet tile generation. +* `--tmpdir=/var/scratch`: ensure there is at least 512GB of scratch space. diff --git a/basemaps/downloads.md b/basemaps/downloads.md index d02e076..4e66601 100644 --- a/basemaps/downloads.md +++ b/basemaps/downloads.md @@ -9,19 +9,43 @@ outline: deep The **Protomaps Basemap** is a general purpose vector *base map* - city labels, roads, water features and other essential location context derived from [OpenStreetMap](https://openstreetmap.org). It's available as a single PMTiles archive, distributed as an [Open Database License](https://opendatacommons.org/licenses/odbl/) Produced Work (OpenStreetMap attribution required) +A full planet file is roughly **120 gigabytes**, including zoom levels from 0 to 15. + +Please note that **URLs may change** and hotlinking to these downloads are discouraged. Instead, you should copy the tileset to your own [Cloud Storage](/pmtiles/cloud-storage). + +* The generation of the planet basemap is open source at [github.com/protomaps/basemaps](http://github.com/protomaps/basemaps). + + ## Current Version -The Version 3 Protomaps basemap daily build channel is available at [maps.protomaps.com/builds](https://maps.protomaps.com/builds). +The Version 4 Protomaps basemap daily build channel is available at [maps.protomaps.com/builds](https://maps.protomaps.com/builds). This is compatible with `@protomaps/basemaps` style v4.0.0 and newer. -## Previous Version +[BLAKE3](https://github.com/BLAKE3-team/BLAKE3/releases/) hashes are provided for daily builds. Use `b3sum` to verify the integrity of your downloaded file. -The version 2 basemap is `protomaps-basemap-opensource-20230408.pmtiles` +A mirror in the AWS `us-west-2` is available on [Source Cooperative (beta)](https://beta.source.coop) at the [protomaps/openstreetmap](https://beta.source.coop/repositories/protomaps/openstreetmap/) repository. This mirrors the most recent daily build only. -You can download the planet archive at this link (⚠ file is over 100GB): +### Build History -[https://r2-public.protomaps.com/protomaps-sample-datasets/protomaps-basemap-opensource-20230408.pmtiles](https://r2-public.protomaps.com/protomaps-sample-datasets/protomaps-basemap-opensource-20230408.pmtiles) +The daily builds bucket retains: -Please note that this **URL may change** and hotlinking to it is discouraged. Instead, you should copy the tileset to your own [Cloud Storage](/pmtiles/cloud-storage). +* All builds for the past week. +* Weekly monday builds for the past month. +* The latest build for each version (major + minor + patch) beyond that. -* The generation of the planet basemap is open source at [github.com/protomaps/basemaps](http://github.com/protomaps/basemaps). +## Partial Downloads + +To download a cutout of a specific region, rather than the entire world map, see the CLI's [extract command](/pmtiles/cli#extract). + +If you don't need all 16 zoom levels of detail, use the `--maxzoom` option of `pmtiles extract`. Each additional zoom level roughly doubles the size of the file. + +## Terrain + +### Mapterhorn + +The [Mapterhorn](http://mapterhorn.com) project distributes Terrarium-encoded RGB tiles aggregated from multiple global data sources in PMTiles format. Download the full `.pmtiles` or get a partial download with `pmtiles extract` at the [Mapterhorn Data Access documentation](https://mapterhorn.com/data-access/). + +### Tilezen Joerd (legacy) + +The [AWS Registry of Open Data](https://registry.opendata.aws/terrain-tiles/) hosts Terrarium-encoded RGB tiles generated by the [Joerd](https://github.com/tilezen/joerd) project. Below is a link of zooms 0 to 12 of this tileset, provided as-is. See the [Joerd docs](https://github.com/tilezen/joerd/blob/master/docs/attribution.md) for attribution requirements. +[terrarium-z12.pmtiles](https://r2-public.protomaps.com/protomaps-sample-datasets/terrarium-z12.pmtiles) [(preview)](https://pmtiles.io/?url=https%3A%2F%2Fr2-public.protomaps.com%2Fprotomaps-sample-datasets%2Fterrarium-z12.pmtiles#map=0.7/0/0) diff --git a/basemaps/extract_vs_clip.png b/basemaps/extract_vs_clip.png new file mode 100644 index 0000000..597ff95 Binary files /dev/null and b/basemaps/extract_vs_clip.png differ diff --git a/basemaps/flavors.md b/basemaps/flavors.md new file mode 100644 index 0000000..e725290 --- /dev/null +++ b/basemaps/flavors.md @@ -0,0 +1,59 @@ +--- +title: Basemap Flavors +outline: deep +--- + + + +# Basemap Flavors + +These examples use the preferred [MapLibre GL JS](/basemaps/maplibre) library. + +The `Flavor` TypeScript interface is the preferred way to customize the basemap style. See the shape of the interface at the [@protomaps/basemaps TypeScript docs](https://maps.protomaps.com/typedoc/interfaces/Flavor.html). + +A `Flavor` is a plain object of color definitions and optional properties such as font names, landcover shades and POI properties. You can define a `Flavor` yourself for a custom style, similar to a text editor color scheme, or use one of the default named flavors as a base. + +## Default Flavors + +These flavors are included as part of the `@protomaps/basemaps` package. + +### light + +A general-purpose basemap with icons. + + + +### dark + +A general-purpose basemap with icons. + + + +### white + +A flavor for data visualization. + + + +### grayscale + +A flavor for data visualization. + + + +### black + +A flavor for data visualization. + + + +## Overriding Defaults + +Use [ES6 spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) to override any part of the Flavor object. For example, to color buildings red: + +```ts +import { namedFlavor } from "@protomaps/basemaps" +let flavor = {...namedFlavor("light"),buildings:"red"} +``` diff --git a/basemaps/layers.md b/basemaps/layers.md index 8be773d..7267585 100644 --- a/basemaps/layers.md +++ b/basemaps/layers.md @@ -2,80 +2,410 @@ title: Basemap Layers outline: deep --- + # Basemap Layers -OpenStreetMap layers documentation. +The Protomaps basemap is built on [OpenStreetMap](https://openstreetmap.org) and [Natural Earth](https://naturalearthdata.com) data. It does not include all data and tags from OSM; instead it is designed to strike a balance between tile size and completeness, for use as a general-purpose context map. + +The organization of layers and tags is derived from the [open source Tilezen project](https://tilezen.readthedocs.io/en/latest/layers/). The scope of contents and choice of data inclusion at certain zoom levels is intended to mirror the reference implementations of Tilezen styles such as [Bubble Wrap](https://tangrams.github.io/bubble-wrap/). -::: warning -This section is under construction. +The current version is **Version 4**. -For the previous version of the layers, see [Layers Version 2](/basemaps/layers_v2) -::: +## Common Tags - +| Key | Values | Description | +| -------------------------------------------------- | ------- | ------------------------------------------ | +| `name`, `name*`, `name:*`, `pgf:name:*`, `script*` | string | see [Localization](/basemaps/localization) | +| `sort_rank` | integer | Importance ranking used for rendering | +| `min_zoom` | integer | Suggested zoom level to limit display | ## boundaries -`kind` + + +| Key | Values | Description | +| ------------- | ----------------------------------------- | --------------------------------- | +| `kind` | `country`, `region`, `county`, `locality` | | +| `kind_detail` | integer | the minimum admin_level from OSM | +| `brk_a3` | | `brk_a3` value from Natural Earth | +| `disputed` | boolean | | ## buildings + -Buildings from OpenStreetMap. +Buildings and address points from OpenStreetMap. z0-14 contains merged buildings, even disconnected ones. z15+ contains individual OSM equivalent buildings. + +| Key | Values | Description | +| ------------------ | :--------------------------------------: | -----------------------------------------------------------: | +| `kind` | `address`, `building`, `building_part` | Whether it is an address point, whole building or one part. | +| `addr_housenumber` | string | Address number for `kind=address`. | +| `height` | number | May be quantized at low zoom levels. | +| `min_height` | number | May be quantized at low zoom levels. | +| `layer` | integer | Layer position relative to other buildings. | -| Key | Values | Description | -| ------------- | :-----------: | ----: | -| `pmap:kind` | `building`, `building_part`| Whether it is a whole building or one part. | -| `height` | number | May be quantized at low zoom levels. | -| `min_height` | number | May be quantized at low zoom levels. | -| `layer` | integer | Layer position relative to other buildings. | ## earth -`kind` + -## landuse +Polygons from the Natural Earth 50m `land` theme for z0-z4, 10m for z5, preprocessed land polygons from [OSMCoastline](https://osmdata.openstreetmap.de) for z6+. -`kind` +| Key | Values | Description | +| ------ | :-----: | ----------: | +| `kind` | `earth` | | -## natural +## landcover - + -## physical_line +Polygons from the Daylight distribution's [landcover](https://daylightmap.org/2023/10/11/landcover.html) theme, for z0-z7. -::: warning -physical_line will be deprecated in v4.0. -::: +| Key | Values | Description | +| ------ | :---------------------------------------------------------------------------: | ----------: | +| `kind` | `barren`, `farmland`, `forest`, `glacier`, `grassland`, `scrub`, `urban_area` | | -## physical_point +_NOTE: It's recommended to pair with **natural** layer polygons in from OpenStreetMap at mid- and high-zooms._ -::: warning -physical_point will be deprecated in v4.0. -::: +## landuse + + +Polygons from OpenStreetMap, from a curated subset of `aeroway`, `amenity`, `area:aeroway`, `boundary`, `highway`, `landuse`, `leisure`, `man_made`, `natural`, `place`, `railway`, `tourism` tags, for all zooms. + +| Key | Values | Description | +| ------- | :-------: | ----------------------------------: | +| `kind` | See below | | +| `sport` | string | Which sports are played on a pitch. | + +### Kinds + +| Kind | +| ------------------- | +| `aerodrome` | +| `attraction` | +| `bare_rock` | +| `beach` | +| `cafe` | +| `camp_site` | +| `cemetery` | +| `college` | +| `commercial` | +| `dog_park` | +| `farmland` | +| `farmyard` | +| `footway` | +| `forest` | +| `garden` | +| `glacier` | +| `golf_course` | +| `grass` | +| `grocery` | +| `hospital` | +| `hotel` | +| `industrial` | +| `kindergarten` | +| `library` | +| `marina` | +| `meadow` | +| `military` | +| `national_park` | +| `nature_reserve` | +| `neighbourhood` | +| `orchard` | +| `other` | +| `park` | +| `pedestrian` | +| `pier` | +| `pitch` | +| `platform` | +| `playground` | +| `post_office` | +| `protected_area` | +| `railway` | +| `recreation_ground` | +| `residential` | +| `runway` | +| `sand` | +| `school` | +| `scrub` | +| `stadium` | +| `supermarket` | +| `taxiway` | +| `townhall` | +| `university` | +| `wetland` | +| `wood` | +| `zoo` | ## places -`kind` +Points from OpenStreetMap and Natural Earth, from a curated subset of place tags, for all zooms. + + + +| Key | Values | Description | +| ----------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | ----------: | +| `kind` | `country`, `region`, `locality`, `macrohood`, `neighbourhood` | | +| `kind_detail` | `allotments`, `city`, `country`, `farm`, `hamlet`, `hamlet`, `isolated_dwelling`, `locality`, `neighbourhood`, `province`, `quarter`, `scientific_station`, `state`, `town`, `village` | | +| `capital` | string | | +| `population` | int | | +| `population_rank` | int | | +| `wikidata` | string | | ## pois -`kind` +Points from OpenStreetMap, from a curated subset of aeroway, amenity, attraction, boundary, craft, highway, historic, landuse, leisure, natural, railway, shop, tourism tags, for all zooms. + + + +| Key | Values | Description | +| ---------- | :-------: | ----------: | +| `kind` | See below | | +| `cuisine` | string | | +| `religion` | string | | +| `sport` | string | | +| `iata` | string | | + +_NOTE: The list of kind values is not comprehensive as some raw OSM tag values are passed through in the current version._ + +### Kinds + +| kind | icon | +| ------------------------ | ------------------------------------------------ | +| `aerodrome` | | +| `adult_gaming_centre` | | +| `airfield` | | +| `alpine_hut` | | +| `amusement_ride` | | +| `animal` | | +| `art` | | +| `artwork` | | +| `atm` | | +| `attraction` | | +| `atv` | | +| `baby_hatch` | | +| `bakery` | | +| `bbq` | | +| `beach` | | +| `beauty` | | +| `bed_and_breakfast` | | +| `bench` | | +| `bicycle_parking` | | +| `bicycle_rental` | | +| `bicycle_repair_station` | | +| `boat_storage` | | +| `bookmaker` | | +| `books` | | +| `bureau_de_change` | | +| `bus_stop` | | +| `butcher` | | +| `cafe` | | +| `camp_site` | | +| `car_parts` | | +| `car_rental` | | +| `car_repair` | | +| `car_sharing` | | +| `car_wash` | | +| `car` | | +| `carousel` | | +| `cemetery` | | +| `chalet` | | +| `charging_station` | | +| `childcare` | | +| `clinic` | | +| `clothes` | | +| `college` | | +| `computer` | | +| `convenience` | | +| `customs` | | +| `dentist` | | +| `district` | | +| `doctors` | | +| `dog_park` | | +| `drinking_water` | | +| `emergency_phone` | | +| `fashion` | | +| `firepit` | | +| `fire_station` | | +| `fishing` | | +| `florist` | | +| `forest` | | +| `fuel` | | +| `gambling` | | +| `garden_centre` | | +| `gift` | | +| `golf_course` | | +| `golf` | | +| `greengrocer` | | +| `grocery` | | +| `guest_house` | | +| `hairdresser` | | +| `hanami` | | +| `harbourmaster` | | +| `hifi` | | +| `hospital` | | +| `hostel` | | +| `hotel` | | +| `hunting_stand` | | +| `information` | | +| `jewelry` | | +| `karaoke_box` | | +| `karaoke` | | +| `landmark` | | +| `library` | | +| `life_ring` | | +| `lottery` | | +| `marina` | | +| `maze` | | +| `memorial` | | +| `military` | | +| `mobile_phone` | | +| `money_transfer` | | +| `motorcycle_parking` | | +| `motorcycle` | | +| `national_park` | | +| `nature_reserve` | | +| `naval_base` | | +| `newsagent` | | +| `optician` | | +| `park` | | +| `parking` | | +| `peak` | | +| `perfumery` | | +| `picnic_site` | | +| `picnic_table` | | +| `pitch` | | +| `playground` | | +| `post_box` | | +| `post_office` | | +| `ranger_station` | | +| `recycling` | | +| `roller_coaster` | | +| `sanitary_dump_station` | | +| `school` | | +| `scuba_diving` | | +| `shelter` | | +| `ship_chandler` | | +| `shower` | | +| `slipway` | | +| `snowmobile` | | +| `social_facility` | | +| `stadium` | | +| `station` | | +| `stationery` | | +| `studio` | | +| `summer_toboggan` | | +| `supermarket` | | +| `swimming_area` | | +| `taxi` | | +| `telephone` | | +| `tobacco` | | +| `toilets` | | +| `townhall` | | +| `trail_riding_station` | | +| `travel_agency` | | +| `university` | | +| `viewpoint` | | +| `waste_basket` | | +| `waste_disposal` | | +| `water_point` | | +| `water_slide` | | +| `watering_place` | | +| `wayside_cross` | | +| `wilderness_hut` | | +| `zoo` | | ## roads -`kind` +Linear transportation features designed for movement, including highways, streets, +railways and piers from OpenStreetMap. This layer represents built infrastructure including railways. Refer to the [transit](#transit) layer for passenger services. + + + +| Key | Values | Description | +| -------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | ----------: | +| `kind` | See kinds below | | +| `kind_detail` | `motorway`, `motorway_link`, `trunk`, `trunk_link`, `primary`, `primary_link`, `secondary`, `secondary_link`, `tertiary`, `tertiary_link`, `residential`, `service`, `unclassified`, `road`, `raceway`, `pedestrian`, `track`, `path`, `cycleway`, `bridleway`, `steps`, `corridor`, `sidewalk`, `crossing`, `driveway`, `parking_aisle`, `alley`, `drive-through`, `emergency_access`, `utility`, `irrigation`, `slipway`, `cable_car`, `pier`, `runway`, `taxiway`, `disused`, `funicular`, `light_rail`, `miniature`, `monorail`, `narrow_gauge`, `preserved`, `subway`, `tram` | | +| `ref` | string | | +| `shield_text_length` | int | | +| `network` | string | | +| `oneway` | string | | +| `service` | `siding`, `crossover`, `yard` | | +| `is_link` | boolean | | +| `is_tunnel` | boolean | | +| `is_bridge` | boolean | | + +### Kinds + +| kind | +| ------------ | +| `highway` | +| `major_road` | +| `minor_road` | +| `path` | +| `aerialway` | +| `ferry` | +| `pier` | +| `rail` | +| `aeroway` | ## transit -`kind` +Lines representing scheduled passenger services suitable for rendering on the map, even at lower zoom levels. For physical infrastructure, like highways and railways, see the [roads](#roads) layer. + +This layer is currently empty. + +| Key | Values | Description | +| ------------- | :----: | ----------: | +| `kind_detail` | | | +| `ref` | string | | +| `network` | string | | +| `layer` | int | | +| `route` | string | | +| `service` | string | | ## water -`kind` + + +* Polygons, lines and point labels from OpenStreetMap. + +* Polygons from the Natural Earth 50m `lakes` and `ocean` themes for z0-z4, 10m for z5, preprocessed land polygons from [OSMCoastline](https://osmdata.openstreetmap.de) for z6+. +| Key | Values | Description | +| -------------- | :---------------------------------------------------------------------------------------------: | ----------: | +| `kind` | `water`, `lake`, `playa`, `ocean`, `other` | | +| `kind_detail` | `basin`, `canal`, `ditch`, `dock`, `drain`, `lake`, `reservoir`, `river`, `riverbank`, `stream` | | +| `reservoir` | boolean | | +| `alkaline` | boolean | | +| `intermittent` | boolean | | +| `bridge` | string | | +| `tunnel` | string | | +| `layer` | int | | diff --git a/basemaps/leaflet.md b/basemaps/leaflet.md index 9bfbc46..267ccb6 100644 --- a/basemaps/leaflet.md +++ b/basemaps/leaflet.md @@ -5,6 +5,26 @@ outline: deep # Basemaps for Leaflet -::: warning -This section is under construction. -::: \ No newline at end of file +The simplest way to include a map in your application via script includes tag: + +```js + + +``` + +To use with a bundler: + +``` +npm add protomaps-leaflet +``` + +## Customization + +The `flavor` option must be one of `light`, `dark`, `white`, `grayscale`, `black`. + +The `lang` option can be one of the [supported languages](/basemaps/localization). + diff --git a/basemaps/localization.md b/basemaps/localization.md new file mode 100644 index 0000000..b271ae6 --- /dev/null +++ b/basemaps/localization.md @@ -0,0 +1,300 @@ +--- +title: Basemap Localization +outline: deep +--- + + +# Basemap Localization + +Protomaps has several localization options for names used in text labels. + + + +## Local Names + +Protomaps follows OpenStreetMaps's convention where a features's primary name value is is the most common name in the local language(s). + +In practice, this is most often a single name value like: + +- `London` the locality is represented as a simple key, value pair: `name` = `London` + +However, many places have more than one common local languages and Protomaps passes thru OpenStreetMap's convention of concatenating multiple names with a `/` or `-` deliminator into a single name value, like: + +- `Switzerland` the country is represented as a complex key, value pair: `name` = `Schweiz/Suisse/Svizzera/Svizra` + +For transnational places involving many countries and languages, like `sea` features, the default name value can get quite long and unwiedly! + +### `name`, `name2`, and `name3` + +A script or writing system is the way how languages are written. For example, English uses the Latin script, Greek uses the Greek script, and Chinese uses the Han script. + +If a name from OpenStreetMap, which is the de-facto primary local name, contains text in more than one script, then Protomaps breaks up the name into segments. There can be up to 3 segments: `name`, `name2`, and `name3`. Each segment should have a unique script. + +Protomaps stores the scripts used for `name`, `name2`, and `name3` in separate script tags called `script`, `script2`, and `script3`. + +If `script*` is not present on a name, then it means that the name uses the `Latin` script. + +Sometimes segmentation into single scripts fails due for example inconsistent usage of alphabets. In that case `script` is set to `Mixed`. + +In Japanese, the `Han`, `Hiragana`, and `Katakana` scripts are often mixed in one name. Should any two of these scripts appear in a name we set `script` to `Mixed-Japanese`. + +Let us look at some examples: + +#### Zürich +``` +name = Zürich +(script absent) +(name2 absent) +(script2 absent) +(name3 absent) +(script3 absent) +``` + +The OpenStreetMap name for "Zürich" only uses the Latin script so we export `name` and but omit `script` (implying the script of the `name` is `Latin`). + +#### 香港 Hong Kong +``` +name = 香港 +script = Han +name2 = Hong Kong +(script2 absent) +(name3 absent) +(script3 absent) +``` + +The OpenStreetMap name for Hong Kong is "香港 Hong Kong". We break this up into `name` and `name2` in Protomaps. Since the script of `name2` is `Latin`, the `script2` tag is omitted. The script of `name` is `Han` which is encoded in `script`. + +#### Casablanca ⵜⵉⴳⵎⵉ ⵜⵓⵎⵍⵉⵍⵜ الدار البيضاء +``` +name = Casablanca +(script absent) +name2 = ⵜⵉⴳⵎⵉ ⵜⵓⵎⵍⵉⵍⵜ +script2 = Tifinagh +name3 = الدار البيضاء +script3 = Arabic +``` + +Casablanca in OpenStreetMap is stored as "Casablanca ⵜⵉⴳⵎⵉ ⵜⵓⵎⵍⵉⵍⵜ الدار البيضاء". In Protomaps we break this label up into 3 parts. Since the text in `name` uses the `Latin` script, we omit the `script` tag. The other two parts use the Tifinagh and Arabic script. + +## Translated Names + +Protomaps supports name translations for 41 languages. Translated names are stored with a `name:{language_code}` formatting like OpenStreetMap. + +More than 100 countries recognize 2 or more official languages – and some like Bolivia, India, and South Africa recognize more than 10 official languages each! + +A single official language is used in most remaining countries. There are a few countries where no official language has been designated – like in the United States. + +Going back to our London example, English is the predominant (unofficial) language in the United Kingdom: + +- `name:en` = `London` + +Extending our London example, many other languages include [exonym and endonym](https://simple.wikipedia.org/wiki/Exonym_and_endonym#:~:text=An%20exonym%20is%20a%20name,place%20and%20language%20call%20themselves.) values in both Latin script and non-Latin scripts: + +- `name:ar` = `لندن` +- `name:de` = `London` +- `name:es` = `Londres` +- `name:fr` = `Londres` +- `name:it` = `Londra` +- `name:pt` = `Londres` +- `name:zh-Hans` = `伦敦` +- `name:zh-Hant` = `倫敦` +- _... many other localized values..._ + +Going back to our Switzerland example, each of the official languages would have a specific language name value (in this case German `de`, French `fr`, Italian `it`, and Romansh `rm`), like: + +- `name:de` = `Schweiz` +- `name:fr` = `Suisse` +- `name:it` = `Svizzera` +- `name:rm` = `Svizra` +- _... many other localized values..._ + +Extending our Switzerland example with exonym and endonym from other languages: + +- `name:ar` = `سويسرا` +- `name:en` = `Switzerland` +- `name:es` = `Switzerland` +- `name:pt` = `Suíça` +- `name:zh-Hans` = `瑞士` +- `name:zh-Hant` = `瑞士` +- _... many other localized values..._ + + +### List of Supported Languages + +| Language | Native Name | `name:*` Tag | Script | +| ----- | ----- | ----- | ----- | +| Arabic | اَلْعَرَبِيَّةُ | `name:ar` | `Arabic` | +| Bulgarian | български | `name:bg` | `Cyrillic` | +| Chinese (Simplified) | 中文 汉语 | `name:zh-Hans` | `Han` | +| Chinese (Traditional) | 中文 漢語 | `name:zh-Hant` | `Han` | +| Croatian | hrvatski | `name:hr` | `Latin` | +| Czech | čeština | `name:cs` | `Latin` | +| Danish | dansk | `name:da` | `Latin` | +| Dutch | Nederlands | `name:nl` | `Latin` | +| English | English | `name:en` | `Latin` | +| Estonian | eesti keel | `name:et` | `Latin` | +| Finnish | suomi | `name:fi` | `Latin` | +| French | français | `name:fr` | `Latin` | +| German | Deutsch | `name:de` | `Latin` | +| Greek | Νέα Ελληνικά | `name:el` | `Greek` | +| Hebrew | עברית | `name:he` | `Hebrew` | +| Hindi | हिन्दी | `name:hi` | `Devanagari` | +| Hungarian | magyar | `name:hu` | `Latin` | +| Indonesian | bahasa Indonesia | `name:id` | `Latin` | +| Irish | Gaeilge | `name:ga` | `Latin` | +| Italian | italiano | `name:it` | `Latin` | +| Japanese | 日本語 | `name:ja` | `Han`, `Katakana`, `Hiragana`, `Mixed-Japanese` | +| Korean | 한국어 | `name:ko` | `Hangul` | +| Latvian | latviešu valoda | `name:lv` | `Latin` | +| Lithuanian | lietuvių kalba | `name:lt` | `Latin` | +| Maltese | lingwa Maltija | `name:mt` | `Latin` | +| Marathi | मराठी | `name:mr` | `Devanagari` | +| Nepali | नेपाली | `name:ne` | `Devanagari` | +| Norwegian | norsk | `name:no` | `Latin` | +| Persian | فارسی | `name:fa` | `Arabic` | +| Polish | Język polski | `name:pl` | `Latin` | +| Portuguese | português | `name:pt` | `Latin` | +| Romanian | român | `name:ro` | `Latin` | +| Russian | русский язык | `name:ru` | `Cyrillic` | +| Slovak | slovenský | `name:sk` | `Latin` | +| Slovenian | slovenski | `name:sl` | `Latin` | +| Spanish | español | `name:es` | `Latin` | +| Swedish | svenska | `name:sv` | `Latin` | +| Turkish | Türkçe | `name:tr` | `Latin` | +| Ukrainian | Українська мова | `name:uk` | `Cyrillic` | +| Urdu | اردو | `name:ur` | `Arabic` | +| Vietnamese | Tiếng Việt | `name:vi` | `Latin` | + +NOTE: `Mixed-Japanese` is a custom `script` value used for labels that contain Hiragana or Katakana mixed with a second or third script. In Japanese, these two scripts often appear in combination with others. + +NOTE 2 : Values in `script*` follow the [Unicode Standard Annex #24: Script Names](https://www.unicode.org/reports/tr24/). + +## Styling + +For each supported language, Protomaps distributes a localized MapLibre style.json file which shows labels in a target language. Country labels are only shown in the target language, place and street labels can have multiple languages. + +The following set of rules is used: + +- Show local names only if they use a different script than the target language +- If the target language is not available, fallback to name:en if the local script is not Latin +- Hide text in scripts that cannot be rendered correctly by MapLibre, such as Khmer or Bengali + +### Example: Milano + +For a map localized to English, we only use `name:en = Milan` since the local `name = Milano` uses the Latin script which is used in English as well. The label would be: + +``` +Milan +``` + +For a map localized to Greek, we would use `name:el = Μιλάνο` in the first line and since that is a different script from Latin, we would also include the local `name = Milano` in the second line: + +``` +Μιλάνο +Milano +``` + +## Positioned glyph font `pgf:name:*` values + +Protomaps adds additional names for a small set of language scripts, currently just the `Devanagari` script used for Hindi (`name:hi` and `pgf:name:hi`) and related languages. + +Rendering text in web browsers works for almost all languages and scripts and feels like magic. However, specialized map renderers like MapLibre have to reimplement text rendering and text layout which is complicated when text needs to be curved along linear map features instead of placed only horizontally or vertically. MapLibre normally assumes a one-to-one mapping between glyphs and Unicode codepoints that also exist in MapLibre font files (aka "font stacks") to accomplish the layout for a large but limited number of scripts. Plugins have been developed to extend MapLibre for **right-to-left** scripts like Arabic and Hebrew, and MapLibre has built-in support for **CJK scripts** like Chinese, Japanese, and Korean. + +To facilitate Protomap's support of additional, non-supported scripts in MapLibre (like the Devanagari script used by the Hindi language), Protomaps exports names with "positioned glyphs" so MapLibre can use codepoints as indices of positioned glyphs in an additional custom "font stack". While the raw `pgf:name:*` values look like gibberish when inspecting the raw values, they render correctly in MapLibre to the end user. + +See more: + +- [Traditional MapLibre Text Rendering](https://oliverwipfli.ch/about-text-rendering-in-maplibre-2023-10-17/) +- [Devanagari Positioned Glyph Fonts](https://oliverwipfli.ch/devanagari-in-the-protomaps-basemap-with-a-positioned-glyph-font-for-maplibre-2024-06-30/) + + +#### MapLibre supported scripts and languages + +| Script | Languages | +| ------- | ---------| +| `Latin` | AFRIKAANS, ALBANIAN, AZERBAIJANI (also `Cyrillic`, `Arabic`), BASQUE, BOSNIAN (also `Cyrillic`), , CATALAN, CROATIAN, CZECH, DANISH, DUTCH, ENGLISH, ENGLISH (AUSTRALIAN), ENGLISH (GREAT BRITAIN), ESTONIAN, FINNISH, FILIPINO, FRENCH, FRENCH (CANADA), GALICIAN, GERMAN, HUNGARIAN, ICELANDIC, INDONESIAN, ITALIAN, KAZAKH (also `Latin`, `Arabic`, `Cyrillic`), LATVIAN, LITHUANIAN, MALAY (also `Arabic`, `Thai`), NORWEGIAN, POLISH, PORTUGUESE, PORTUGUESE (BRAZIL), PORTUGUESE (PORTUGAL), ROMANIAN, SERBIAN (also `Cyrillic`), SLOVAK (also `Cyrillic`), SLOVENIAN, SPANISH, SPANISH (LATIN AMERICA), SWAHILI, SWEDISH, TURKISH, UZBEK (also `Cyrillic`, `Arabic`), VIETNAMESE, ZULU | +| `Arabic` | ARABIC, FARSI, URDU, KAZAKH (also `Cyrillic`, `Latin`), KYRGYZ (also `Cyrillic`) | +| `Cyrillic` | BELARUSIAN, BULGARIAN (also `Latin`), KAZAKH (also `Latin`, `Arabic`), KYRGYZ (also `Arabic`), MACEDONIAN, MONGOLIAN, RUSSIAN, SERBIAN (also `Latin`), UKRAINIAN | +| `Han` | CHINESE, CHINESE (SIMPLIFIED), CHINESE (HONG KONG), CHINESE (TRADITIONAL) | +| `Amharic` | AMHARIC | +| `Armenian` | ARMENIAN | +| `Hangul` | KOREAN | +| `Hebrew` | HEBREW | +| `Japanese` | JAPANESE | +| `Georgian` | GEORGIAN | +| `Greek` | GREEK | +| `Mongolian` | MONGOLIAN (also `Cyrillic`) | + +NOTE: Right-to-left scripts and languages like Arabic and Hebrew requires a special [RTL text MapLibre plugin](https://maplibre.org/maplibre-gl-js/docs/examples/mapbox-gl-rtl-text/). + +#### MapLibre partial support + +Requires paired positioned glyph font [font stack](https://maplibre.org/maplibre-style-spec/glyphs/) paired with `pgf:name:*` values. The PGF fontstacks used by the Protomaps basemaps are available at https://github.com/protomaps/basemaps-assets/tree/main/fonts. + +| Script | Languages | +| ------- | ---------| +| `Devanagari` | HINDI, MARATHI, NEPALI | + +#### MapLibre no support + +| Script | Languages | +| ------- | ---------| +| `Gujarati` | GUJARATI | +| `Kannada` | KANNADA | +| `Bengali` | BENGALI | +| `Burmese` | BURMESE | +| `Khmer` | KHMER | +| `Lao` | LAO | +| `Malayalam` | MALAYALAM | +| `Punjabi` | PUNJABI | +| `Sinhalese` | SINHALESE | +| `Tamil` | TAMIL | +| `Telugu` | TELUGU | +| `Thai` | THAI + +_NOTE: This is a partial listing of scripts and languages._ + +These non-supported MapLibre languages are primarily found in India and countries in south-east Asia. + +## Dual Language Labels + +With the data present in the tiles it is possible to create dual language labels, i.e., labels in two target languages. + +For example, to localize a map to Dutch (nl) and French (fr), one can use the following json snippet in a MapLibre Style: + +```json +"text-field": [ + "case", + [ + "all", + ["has", "name:nl"], + ["has", "name:fr"], + ], + // both languages are present + [ + "case", + ["==", ["get", "name:nl"], ["get", "name:fr"]], + // both languages are identical, only show one + ["get", "name:nl"], + // languages not identical, show both + [ + "format", + ["get", "name:nl"], {}, + "\n", {}, + ["get", "name:fr"], {}, + ], + ], + [ + "all", + ["!", ["has", "name:nl"]], + ["!", ["has", "name:fr"]], + ], + // none of the languages is present, use default + ["get", "name"], + // only one language is present + ["coalesce", "name:nl", "name:fr"], +] +``` + diff --git a/basemaps/lodz_viewer.png b/basemaps/lodz_viewer.png new file mode 100644 index 0000000..af61681 Binary files /dev/null and b/basemaps/lodz_viewer.png differ diff --git a/basemaps/maplibre.md b/basemaps/maplibre.md index cf5823a..1cf7a2a 100644 --- a/basemaps/maplibre.md +++ b/basemaps/maplibre.md @@ -5,20 +5,58 @@ outline: deep # Basemaps for MapLibre +## Assets -The `protomaps-themes-base` NPM module contains basemap layer definitions compatible with OpenStreetMap downloads from Protomaps. +To render a full basemap, you'll need not only a style and a tileset, but also MapLibre [fontstack](https://maplibre.org/maplibre-style-spec/glyphs/) and [spritesheet](https://maplibre.org/maplibre-style-spec/sprite/) assets. + +The assets referenced by the `glyphs` and `sprite` style properties can be downloaded as ZIP files at the [basemaps-assets](http://github.com/protomaps/basemaps-assets) repository, if you need to host them yourself or offline. + +### Fonts + +The `glyphs` key references a URL hosting pre-compiled fontstacks, required for displaying text labels in MapLibre. Fontstacks can be created with the [font-maker](https://github.com/maplibre/font-maker) tool. + +```js +glyphs:'https://protomaps.github.io/basemaps-assets/fonts/%7Bfontstack%7D/%7Brange%7D.pbf' +``` + +When a style layer defines a `text-font` like `Noto Sans Regular`, this will create requests for a URL like `https://protomaps.github.io/basemaps-assets/fonts/Noto%20Sans%20Regular/0-255.pbf`. + + +You can view a list of available fonts [in the GitHub repository](https://github.com/protomaps/basemaps-assets/tree/main/fonts). + +### Sprites + +The `sprite` key references a URL specific to one of [the default flavors](/basemaps/flavors): + +```js +sprite: "https://protomaps.github.io/basemaps-assets/sprites/v4/light" +``` + +These are required for townspots, highway shields and point of interest icons. + +## Loading styles as JSON + +Because [MapLibre styles](https://maplibre.org/maplibre-style-spec/) are JSON documents, the simplest way to define a style in your application is with static JSON. You can use the `Get style JSON` feature of [maps.protomaps.com](https://maps.protomaps.com) to generate static JSON for a specific flavor and style package version. + +## Creating styles programatically + +For more control and less code, you can add use the [`@protomaps/basemaps`](https://www.npmjs.com/package/@protomaps/basemaps) NPM package as a dependency. + +### Using the npm package ```bash -npm install protomaps-themes-base +npm install @protomaps/basemaps ``` + ```js -import layers from 'protomaps-themes-base'; +import { layers, namedFlavor } from '@protomaps/basemaps'; ``` ```js style: { - version:8, + version: 8, glyphs:'https://protomaps.github.io/basemaps-assets/fonts/%7Bfontstack%7D/%7Brange%7D.pbf', + sprite: "https://protomaps.github.io/basemaps-assets/sprites/v4/light", sources: { "protomaps": { type: "vector", @@ -27,21 +65,26 @@ style: { attribution: 'Protomaps © OpenStreetMap' } }, - layers: layers("protomaps","light") + layers: layers("protomaps",namedFlavor("light"),{lang:"en"}) } ``` -the default export from `protomaps-themes-base` is a function that takes 2 arguments: +the `layers` from `@protomaps/basemaps` is a function that takes 3 arguments: -* the source name of the basemap. +* the source name of the basemap, like `protomaps` in the `sources` example above. -* the theme, one of `light`, `dark`, `white`, `black`, `grayscale` or `debug`. +* A [flavor object](/basemaps/flavors); the defaults can be fetched `namedFlavor` with `light`, `dark`, `white`, `black`, `grayscale`. -## Fonts +* An options object: to display labels. pass a `lang` key. Pass `labelsOnly` to display only labels. -The fonts referenced by the `glyphs` style key can be downloaded as a ZIP at the [basemaps-assets](http://github.com/protomaps/basemaps-assets) GitHub repository. +### Using a CDN -Valid font names are: `Noto Sans Regular`, `Noto Sans Medium`, `Noto Sans Italic` +Loading the `@protomaps/basemaps` package from NPM will define the `basemaps` global variable. -Prior to version 2.0.0-alpha.3, the Glyphs URL was `https://cdn.protomaps.com/fonts/pbf/{fontstack}/{range}.pbf`. +```html + +``` +```js +layers: basemaps.layers("protomaps",basemaps.namedFlavor("light"),{lang:"en"}) +```` diff --git a/basemaps/openlayers.md b/basemaps/openlayers.md deleted file mode 100644 index 24005b1..0000000 --- a/basemaps/openlayers.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Basemaps for OpenLayers -outline: deep ---- - -# Basemaps for OpenLayers - -::: warning -This section is under construction. -::: \ No newline at end of file diff --git a/basemaps/styles.md b/basemaps/styles.md deleted file mode 100644 index ba5263a..0000000 --- a/basemaps/styles.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Basemap Styles -outline: deep ---- - -# Basemap Styles - -::: warning -This section is under construction. -::: \ No newline at end of file diff --git a/components/CostCalculator.vue b/components/CostCalculator.vue new file mode 100644 index 0000000..5cd69bb --- /dev/null +++ b/components/CostCalculator.vue @@ -0,0 +1,380 @@ + + + + + diff --git a/components/Icon.vue b/components/Icon.vue new file mode 100644 index 0000000..8eff5cf --- /dev/null +++ b/components/Icon.vue @@ -0,0 +1,50 @@ + + + + + diff --git a/components/MaplibreMap.vue b/components/MaplibreMap.vue index b155efb..9a0c48e 100644 --- a/components/MaplibreMap.vue +++ b/components/MaplibreMap.vue @@ -1,7 +1,11 @@ - diff --git a/deploy/aws.md b/deploy/aws.md index 9343255..b91bb62 100644 --- a/deploy/aws.md +++ b/deploy/aws.md @@ -5,145 +5,64 @@ outline: deep # AWS Integration +The AWS Deployment option is based on [CloudFormation](https://aws.amazon.com/cloudformation/), which automates the creation and deletion of all resources. You don't need to install anything; simply upload a YAML to the AWS Console. + +At the end of this walkthrough, you'll have a CDN-cached ZXY API, compatible with all major map renderers, serving tiles from a private S3 bucket. + ## Installation ### 1. Upload to S3 +The CloudFormation template is designed to work with an existing S3 bucket. File names must include only [S3 safe characters](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-guidelines). + +If you need to create a new bucket: + * Open the [S3 Console](https://s3.console.aws.amazon.com/s3/home) and choose **Create Bucket**. -* The name must be globally unique. Choose any region, just remember the **region name.** +* Choose a globally unique bucket name, and any region, just remember the **region name.** * We'll use `protomaps-example` as a placeholder bucket name. * Leave the default *ACLs disabled* and *Block all public access* setting. - * Leave other options as the default and proceed with Create Bucket. -* **Upload** a PMTiles archive: we'll use `my_file.pmtiles` as an example: to your bucket via the Web Console or a tool like `pmtiles` or `rclone`. - -### 2. Lambda function - -* Open the **Lambda** dashboard in the **same region as your bucket.** -* Choose **Create Function**. - * Name your function `protomaps`. - * For Runtime, leave the default choice `Node.js 18.x`. - * For Architecture, choose `arm64`. - * Under Change Default Execution Role, leave the default `Create a new role with basic Lambda Permissions`. - * This will auto-generate a role name. - * Under Advanced Settings, Choose **Enable Function URL.** - * Under **Auth Type**, choose `NONE`. - * Proceed with Create Function. -* On the Configuration tab, choose **General Configuration** > **Edit**. - * set `Memory` to **512 MB**. This is required, and more cost effective than the default of 128. -* On the Configuration tab, choose **Environment Variables** > **Edit**. - * set `BUCKET` to your unique **bucket name** from Step 1. - * set `PUBLIC_HOSTNAME` to the **public custom domain name you'll assign to your CloudFront distribution.** *TileJSON responses won't work without setting this.* Example: `tiles.example.com` -* In the **Code** tab, replace the code contents with this [JavaScript code](https://protomaps.github.io/PMTiles/lambda_function.zip). -* Choose **Deploy** to deploy the function. - -### 3. Lambda role permissions - -* In the **Configuration** > **Permissions** tab, follow the link under **Execution Role > Role Name** to navigate to the function's IAM role. -* On the right side, choose **Add Permissions > Create Inline Policy**. -* Choose the **JSON** tab and paste in the following: - -(Replace `protomaps-example` with your bucket created in Step 1) - -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "VisualEditor0", - "Effect": "Allow", - "Action": "s3:GetObject", - "Resource": "arn:aws:s3:::protomaps-example/*" - } - ] -} -``` - -* Give this policy any name eg `protomaps-lambda` and **Create Policy**. -* Return to your Lambda function's **Configuration** and **Function URL** page. - -The Function URL that looks like `https://AAAA.lambda-url.region-name.on.aws/` is now active. - -Make a test request for the `/my_file/0/0/0.mvt` (or `.png`, `.jpg` - whatever matches your data) path in your browser. This should succeed with your tile data! - -::: warning -This Public Lambda URL should not be used directly by browsers because it lacks caching and CORS headers, which we'll configure next. -::: - -### 4. CloudFront - -* Navigate to the CloudFront Dashboard and choose **Create Distribution**. + * Leave other options as the default and proceed with **Create Bucket.** +* **Upload** a PMTiles archive. For example, save [this file](https://pmtiles.io/protomaps(vector)ODbL_firenze.pmtiles) as `example.pmtiles`. Upload to your bucket via the Web Console or [a tool like rclone.](/pmtiles/cloud-storage#uploading) -* Enter your Lambda Function URL under **Origin Domain**. +### 2. CloudFormation Template -* for Cache Policy, choose **CachingOptimized** which sets a default TTL of 86400 seconds. +1. In the CloudFormation console for your AWS region, choose **Create Stack > With new resources (standard)**. -* for Viewer Protocol Policy, choose **Redirect HTTP to HTTPS**. +2. Choose **Specify Template > Upload a template file** and upload the file [cloudformation-stack.yaml](http://pmtiles.io/cloudformation-stack.yaml). -* Under Response Headers Policy, choose **Create Policy**. +3. Provide a stack name of your choice. - * enter a name `protomaps-cors` +4. for **Parameters**, specify: - * Enable the slider **Configure CORS**. - - * Choose **Customize** under Access-Control-Allow-Origin and enter full allowed origins e.g. `https://example.com` - - * Leave other settings as the default and proceed with **Create**. - - * Return to the CloudFront Configuration and choose `protomaps-cors` in the **Response headers policy** dropdown (you might need to refresh). - -* Under Settings, check **HTTP/3** in addition to HTTP/2. - -* Enter a **Description** like `protomaps`. - -* Proceed with Create Distribution. - -This may take a few minutes, where the `Last modified` value will display `... Deploying`. When that's complete, you will have a working CloudFront distribution at a URL like `AAAA.cloudfront.net` that can be accessed directly from browsers. - -Accessing your Distribution from a web map should verify that tiles are cached on second request. Tile headers should include: - -``` -x-cache: Hit from cloudfront -``` + * The allowed CORS origins. By default, all sites (`*`) are authorized to make requests. Specify a comma-separated allowlist of sites e.g. `example.com,example.io`. -You may next want to assign a custom domain name to your distribution through Route 53 and Certificate Manager. + * The name of the bucket from step 1. -## Configuration + * The CloudFront cache TTL, which is how long tiles will be cached at the edge. Default 1 day. -Configure these Lambda environment variables: + * (Optional) the public hostname for TileJSON. If you plan to add a custom domain like `tiles.example.com`, enter that here. Otherwise leave this blank for the default `*.cloudfront.net` hostname. -* `BUCKET`: the S3 bucket name. -* `PMTILES_PATH`: optional, define how a tileset name is translated into an S3 key. Default `{name}.pmtiles` - * Example path setting for objects in a directory: `my_folder/{name}/file.pmtiles` -* ~~`TILE_PATH`: optional, define the URL route of the tiles API. Default `/{name}/{z}/{x}/{y}.pbf`~~ **Deprecated** -* `CORS`: optional, set the value of the `Access-Control-Allow-Origin` response header. Examples: `https://example.com`, `*`. Only supports one origin, so useful for development or staging environments only. For production use you should use CloudFront CORS configuration. -* `CACHE_MAX_AGE`: max age in the CloudFront cache, in seconds. default 86400, or 1 day. -## Accessing your Tiles +5. Proceed with **Next > Submit**, acknowledging that it might create IAM resources. -The default Cloudfront URL for your tiles: +This may take a few minutes to create the CDN distribution. When that's complete, you will have a URL like `AAAA.cloudfront.net` that can be accessed directly from browsers: ``` -https://SUBDOMAIN.cloudfront.net/ARCHIVE_NAME/{z}/{x}/{y}.{ext} +https://SUBDOMAIN.cloudfront.net/TILESET.json # TileJSON for MapLibre +https://SUBDOMAIN.cloudfront.net/TILESET/{z}/{x}/{y}.{ext} ``` -where `{ext}` is the file extension - `mvt`, `jpg`, or `png` - matching your tileset, and `SUBDOMAIN` is found at the **Distribution Domain Name** in the [CloudFront Console](https://us-east-1.console.aws.amazon.com/cloudfront/v3/). - - -## TileJSON - -You can access a [TileJSON](https://github.com/mapbox/tilejson-spec) document for each tileset: +Accessing your Distribution from a web map should verify that tiles are cached on second request. Tile headers should include: ``` -https://PUBLIC_HOSTNAME/ARCHIVE_NAME.json +x-cache: Hit from cloudfront ``` -These endpoints will return a 404 unless the `PUBLIC_HOSTNAME` environment variable is set. - - -## Cache Invalidation +You may next want to assign a custom domain name to your distribution through Route 53 and Certificate Manager and update the public hostname in step 4 above. -* For AWS Cloudfront, issue prefix-based invalidations at the [Cloudfront Console](https://us-east-1.console.aws.amazon.com/cloudfront/v3/home). The first 1000 invalidations per month are free (a prefix = 1 invalidation). -* A cache purge will result in new billable events in Lambda and reads from the origin S3 object. +::: warning +AWS Lambda limits response sizes to 6 MB. This is more than enough for typical web mapping applications; you should optimize your tilesets to fit well under this limit. +::: ## Monitoring @@ -153,33 +72,33 @@ These endpoints will return a 404 unless the `PUBLIC_HOSTNAME` environment varia ### Recommended Metrics * **Cache Hit Rate**: All Metrics > Cloudfront > Per-Distribution Metrics > Requests -* **Lambda Invocations**: All Metrics > Lambda > By Function Name (protomaps) > Invocations +* **Lambda Invocations**: All Metrics > Lambda > By Function Name > Invocations -* **Lambda Execution Time**: All Metrics > Lambda > By Funcion Name (protomaps) > Duration +* **Lambda Execution Time**: All Metrics > Lambda > By Funcion Name > Duration ::: info Typical execution times for a properly configured AWS install are 125 ms p50 (mean), 800 ms p99. ::: - ## Cleanup +Deleting the CloudFormation stack will delete the CloudFront distribution, Lambda function and all associated resources, but leave the bucket untouched. -* **Disable** and then **Delete** the **CloudFront Distribution**. -* Delete the **Lambda function and associated policy** -* Delete the **S3 Bucket.** -* Delete the **IAM role.** -* (Custom domain name) **Delete** the certificate in **Certificate Manager.** -* (Custom domain name) **Delete** the A and AAAA entries in **Route 53**. +## Cache Invalidation +* For AWS Cloudfront, issue prefix-based invalidations at the [Cloudfront Console](https://us-east-1.console.aws.amazon.com/cloudfront/v3/home). The first 1000 invalidations per month are free (a prefix = 1 invalidation). +* A cache purge will result in new billable events in Lambda and reads from the origin S3 object. -## Other Deployment Options +## Lambda Configuration -### Lambda@Edge +The raw Lambda function embedded in the CloudFormation template is also available at [lambda_function.zip](https://pmtiles.io/lambda_function.zip). Note that this must be uploaded as a `.zip` file containing the single file `index.js`. -Lambda@Edge's multi-region features have little benefit when fetching data from S3 in a single region, and Lambda@Edge [doesn't support](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/edge-functions-restrictions.html) environment variables or responses over 1 MB. For globally distributed caching, use CloudFront in combination with Lambda Function URLs. +Lambda environment variables: -### API Gateway +* `BUCKET`: the S3 bucket name. +* `PMTILES_PATH`: optional, define how a tileset name is translated into an S3 key. Default `{name}.pmtiles` + * Example path setting for objects in a directory: `my_folder/{name}/file.pmtiles` +* `CORS`: optional, set the value of the `Access-Control-Allow-Origin` response header. Examples: `https://example.com`, `*`. Only supports one origin, so useful for development or staging environments only. For production use you should use CloudFront CORS configuration. +* ~~`CACHE_MAX_AGE`: max age in the CloudFront cache, in seconds. default 86400, or 1 day.~~ +* `CACHE_CONTROL`: HTTP header value to control caching, default `public, max-age=86400` (1 day). -* your Lambda Proxy Integration route will need to specify a greedy capturing parameter called `proxy` e.g. `/{proxy+}` (the default). -* API Gateway responses will always be GZIP-encoded, to work around binary content detection problems. diff --git a/deploy/azure.md b/deploy/azure.md new file mode 100644 index 0000000..c295ebd --- /dev/null +++ b/deploy/azure.md @@ -0,0 +1,58 @@ +# Microsoft Azure + +PMTiles can be served from a [Azure Container App]() using the [go-pmtiles Docker image](https://hub.docker.com/repository/docker/protomaps/go-pmtiles/general). + +## Blob Storage + +PMTiles should stored in a [Azure Blob Storage](https://azure.microsoft.com/en-us/products/storage/blobs) container. File names must include only [S3 safe characters](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-guidelines). + +Make note of the **Storage Account Name**, region and **container name** (e.g. `main`) for the below steps. + +## Creating an Azure Container App + +1. In [**Create Container App**](https://portal.azure.com/#browse/Microsoft.App%2FcontainerApps), choose the same Azure region as your storage bucket. Create a new **Container Apps Environment** if necessary. + +2. In **Container Details**, name your container and choose **Docker Hub or other registries** as the Image Source. + + * For **Image and Tag** input `protomaps/go-pmtiles:v1.22.1` + + * For **Command Override** input: + +``` + /go-pmtiles, serve, ., --bucket=azblob://main?storage_account=account, --public-url=https://example.com +``` + + * Substitute `main` for your Blob Storage container name, `account` for your Storage Account name, and `https://example.com` for the final user-facing URL you intended your tiles to be served from. If you leave this blank, TileJSON won't work. + +3. In the **Ingress** tab, Enable Ingress and choose **Accepting Traffic from Anywhere**. Enter `8080` for the **Target Port**. + +4. After validation runs, create your Container App. + +## Service Connector + +You Azure Container App needs read access to your Azure Storage Blob. + +After it's initially created, choose **Service Connector (preview) > Create**. + +1. for **Service Type**, choose **Storage - Blob**. + +2. Choose any connection name. + +3. In the **Authentication** tab, choose **Connection String**. Click the **Advanced** tag and rename the `AZURE_STORAGEBLOB_CONNECTIONSTRING` environment variable to `AZURE_STORAGE_CONNECTION_STRING`. + +4. After validation runs, create your Service Connector. + +Your tiles can now be served through your Container App ingress endpoint, e.g. `https://example.name.region.azurecontainerapps.io/tileset/0/0/0.mvt`. + +For TileJSON to work, `tileset.json`, re-configure your Container Command Override with the final user-facing URL for your tiles, such as `tiles.example.com`, `my-tiles.azureedge.net` for Microsoft CDN, etc. + +## Cost and Latency + +* By setting minimum replicas to 0, Azure Container Apps can scale to 0 when there are no requests to be served. However, cold start requests when there are 0 instances can take 10+ seconds to complete. + +* Setting minimum replicas to 1 can eliminate cold starts and only incur [idle usage charges](https://azure.microsoft.com/en-us/pricing/details/container-apps/) when running. + + + + + diff --git a/deploy/cloudflare.md b/deploy/cloudflare.md index 2c6eb4a..fe54912 100644 --- a/deploy/cloudflare.md +++ b/deploy/cloudflare.md @@ -5,73 +5,76 @@ outline: deep # Cloudflare Integration +This guide walks through setting up a ZXY API using Cloudflare R2 Storage and Workers. + +:::warning +Cloudflare R2 is known to have higher latency (500ms or higher) than other Cloud Storage products, but lower storage and no egress costs. Evaluate this as a deployment option alongside others. +::: + ## Installation ### 1. Upload to R2 Uploading via Web UI is limited to 300 MB. -Use [rclone](https://rclone.org/downloads/) to upload larger PMTiles archives to R2. +Use [rclone](/pmtiles/cloud-storage#uploading) to upload larger PMTiles archives to R2. + +This requires a token from **R2 > Manage R2 API Tokens**. Note **Access Key ID**, the **Secret Access Key** and the **Endpoint for S3 Clients** from the API key creation screen. The S3-compatible endpoint should look like: `https://.r2.cloudflarestorage.com`. -Name your uploads to storage with the `.pmtiles` extension. Your tile requests to the Workers URL will look like `/FILENAME/0/0/0.ext` for the archive `FILENAME.pmtiles`. +Name your uploads to storage with the `.pmtiles` extension. Your tile requests to the Workers URL will look like `/NAME/0/0/0.` or `/NAME.json` ([TileJSON](https://github.com/mapbox/tilejson-spec/tree/master/3.0.0)) for the archive `NAME.pmtiles`. File names must include only [S3 safe characters](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-guidelines). -### 2. Create Worker with Web Console +### 2. Manual Option: Create Worker with Web Console -1. In the Workers tab of the Cloudflare dashboard, choose **Create a Service**. +1. In the **Workers & Pages** menu of the Cloudflare dashboard, choose **Create > Create Worker**. -2. Leave the default **HTTP handler** option. +2. Click **Deploy** to publish the sample code. -3. in Settings for your worker, choose Variables > R2 Bucket Bindings > **Add Binding**. +3. **Edit Code** and replace the existing with the bundled [index.js](https://pmtiles.io/index.js) from [PMTiles/serverless/cloudflare](https://github.com/protomaps/PMTiles/tree/main/serverless/cloudflare). - * Create variable with name `BUCKET` and select your R2 bucket from Step 1. +5. Choose **Deploy > Save and Deploy** and leave the code editing window. + +6. In **Settings** of your worker: - * Choose **Save and Deploy**. + * Choose **Variables and Secrets** > **+Add**. Name a variable `ALLOWED_ORIGINS` and set it to `*` to allow all CORS origins. -4. in **Quick Edit**, paste in this code: [index.js](https://protomaps.github.io/PMTiles/index.js). + * Choose **Bindings** > **+Add** > **R2 bucket**. Name your variable `BUCKET` and select your R2 bucket from Step 1. - * Choose **Save and Deploy**. + * Choose **Deploy**. -Your worker should now be active at its `*.workers.dev` domain. +Your worker should now be active at its `*.workers.dev` domain, visible at the **Visit** link. -Make a request for `/FILENAME/0/0/0.EXT` to verify tiles are served. +Make a request for `/TILESET.json` to verify TileJSON is served. -### Alternative: Use Wrangler +### 2. Command-line Option: Use Wrangler 1. Clone the [PMTiles repository](https://github.com/protomaps/PMTiles) and change to the `serverless/cloudflare` directory. -2. `npm install` in `PMTiles/js` to get the dependencies of the core JS library +2. `npm install` in `PMTiles/serverless/cloudflare`. -3. Also `npm install` in `PMTiles/serverless/cloudflare` +3. Copy `wrangler.toml.example` to `wrangler.toml`. -4. Copy `wrangler.toml.example` to `wrangler.toml` +4. Edit `wrangler.toml`, replacing `my-bucket-development` and `my-bucket-production` with your bucket. -5. Edit `wrangler.toml`, replacing `bucket_name` with your bucket. +5. Publish the worker: `npm run deploy` -6. Publish the worker: `npm run deploy` +After the deploy, the `*.workers.dev` subdomain will be printed. + +Make a request for `/TILESET.json` to verify TileJSON is served. ### 3. Create Worker Route For the cache to work, the worker must be assigned a zone on your own domain, not `workers.dev`. -1. In Websites > your domain > DNS, Add a CNAME entry pointing to your `workers.dev` domain: - -![cloudflare image](./cloudflare_1.png) +1. In **Settings > Domains & Routes** for your Worker, add a **Custom Domain** e.g. `subdomain.mydomain.com`. This will create a DNS entry in your Cloudflare site. -2. In Websites > your domain > Workers Routes, Choose **Add Route**. - - * for **Route**, enter `SUBDOMAIN.mydomain.com/*` - - * for **Service**, choose the name of your Worker. for **Environment**, choose `production`. - -![cloudflare image](./cloudflare_2.png) - -Verify your deployment is working on `SUBDOMAIN.mydomain.com` by checking for the `Cf-Cache-Status` header with a value of `HIT` on tile requests. This may take 2-3 attempts. +Verify your deployment is working by checking for the `Cf-Cache-Status` header with a value of `HIT` on successful (HTTP 200) requests. Example with `curl` for vector tiles and [TileJSON](https://github.com/mapbox/tilejson-spec): ```bash curl -v https://subdomain.mydomain.com/FILENAME/0/0/0.mvt +# TileJSON for MapLibre curl -v https://subdomain.mydomain.com/FILENAME.json ``` @@ -81,19 +84,17 @@ Optional environment variables can be set set in `[vars]` of `wrangler.toml` or * `PMTILES_PATH` - A string like `folder/{name}.pmtiles` specifying the path to archives in your bucket. Default `{name}.pmtiles` -* ~~`TILES_PATH` - a string like `prefix/{name}/{z}/{x}/{y}.{ext}` specifying the tile path exposed by the worker. Default `{name}/{z}/{x}/{y}.{ext}`~~ **Deprecated** - * `PUBLIC_HOSTNAME` - Optional, override the absolute hostname in [TileJSON](https://github.com/mapbox/tilejson-spec) responses. Example `tiles.example.com` * `ALLOWED_ORIGINS` - a comma-separated list of allowed CORS origins. Default none. Examples: `https://example.com,https://localhost:3000`, `*` -* `CACHE_MAX_AGE`: max age in the Cloudflare cache, in seconds. default 86400, or 1 day. +* `CACHE_CONTROL`: HTTP header value to control caching, default `public, max-age=86400` (1 day). ## Cost Estimate -* Cloudflare Workers is [$5 USD per month](https://developers.cloudflare.com/workers/platform/pricing) with 10 million requests a month included, plus $0.50 per additional million. -* [Cloudflare R2](https://blog.cloudflare.com/introducing-r2-object-storage/) incurs costs for storage, write requests and read requests. These will only happon on tile cache misses. +* Cloudflare Workers is [$5 USD per month](https://developers.cloudflare.com/workers/platform/pricing) with 10 million requests a month included, plus $0.30 per additional million. +* [Cloudflare R2](https://blog.cloudflare.com/introducing-r2-object-storage/) incurs costs for storage, write requests and read requests. These will only happen on tile cache misses. See the [Cost Calculator](./cost) for estimates based on usage. ## Cache Invalidation -* For Cloudflare, "Purge Cache" applies to all cached resources in the zone (domain). It's recommended to deploy on a dedicated zone for this reason. \ No newline at end of file +* For Cloudflare, "Purge Cache" applies to all cached resources in the zone (domain). It's recommended to deploy on a dedicated zone for this reason. diff --git a/deploy/cloudflare_1.png b/deploy/cloudflare_1.png deleted file mode 100644 index 2cfe909..0000000 Binary files a/deploy/cloudflare_1.png and /dev/null differ diff --git a/deploy/cloudflare_2.png b/deploy/cloudflare_2.png deleted file mode 100644 index db1c614..0000000 Binary files a/deploy/cloudflare_2.png and /dev/null differ diff --git a/deploy/cost.md b/deploy/cost.md new file mode 100644 index 0000000..968b51b --- /dev/null +++ b/deploy/cost.md @@ -0,0 +1,19 @@ +--- +title: Cost Calculator +--- + + + +# Cost Calculator + +Estimate the total cost of a CDN deployment, and compare to hosted basemap providers. + + + +## Notes + +* Reflects only public pricing from Google and other providers, volume pricing requires contacting sales. +* Does not include any free tiers or monthly credit, since those resources may be consumed by other services in your account. +* All calculations are [open source on GitHub.](https://github.com/protomaps/docs/tree/main/components) diff --git a/deploy/google-cloud.md b/deploy/google-cloud.md new file mode 100644 index 0000000..35b702b --- /dev/null +++ b/deploy/google-cloud.md @@ -0,0 +1,62 @@ +# Google Cloud + +PMTiles can be served from a [Cloud Run container](https://console.cloud.google.com/run) using the [go-pmtiles Docker image](https://hub.docker.com/repository/docker/protomaps/go-pmtiles/general). + +## Cloud Storage + +The Cloud Run container is designed to work with existing Cloud Storage buckets. + +If you need to create a new Bucket: + +1. Choose **+ Create** in the [Cloud Storage console](https://console.cloud.google.com/storage). + +2. Pick a globally unique name for your bucket. + +3. For **Location Type**, choose **Region: Lowest latency within a single region** and make a region choice. + +4. Leave **Storage Class** and **Prevent Public Access** as the defaults. + +5. Uncheck **Data Protection > Soft Delete Policy**. + +6. Upload a sample PMTiles into your bucket. File names must include only [S3 safe characters](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-guidelines). + +## Creating a Cloud Run container + +1. In the [Cloud Run console](https://console.cloud.google.com/run), choose **Create Service**. + +2. Choose **Deploy one revision from an existing container image.** + +3. Specify the Container image URL `protomaps/go-pmtiles:v1.22.1`. + +4. Choose a descriptive **Service name** like `protomaps-demo`. + +5. Select the same **Region** as your Cloud Storage bucket. + +6. Select **Allow unauthenticated invocations.** + +7. For CPU Allocation **Service Autoscaling**, leave the defaults (only allocated during processing + 0 minimum instances). + +8. Under **Container(s), Volumes, Networking, Security**: + + 1. Leave the default container port (8080). + + 2. Leave the container command blank (default entry point) + + 3. Specify the arguments: `serve . --bucket=gs://BUCKET --cache-size=500 --public-url=https://example.com` replacing `BUCKET` with the name of your bucket and `https://example.com` with your custom domain. (You may need to enter this manually in the Console for it to interpret spaces correctly.) + + 4. Set `Memory` to 1 GiB. + + 5. Change **Execution Environment** to **2nd Generation**. + + 6. Set **Maximum Number of Instances** to 1. + +By default, Cloud Run projects in the same Project as the Storage bucket will create a Service Account to authenticate to the bucket. + +You should now be able to access your tileset at these URLs: + +``` +https://EXAMPLE.REGION.run.app/TILESET/0/0/0.mvt +https://EXAMPLE.REGION.run.app/TILESET.json # TileJSON,requires --public-url to be set +``` + +Edge caching can be configured through [Google Cloud CDN](https://cloud.google.com/cdn?hl=en) in front of this Cloud Run URL. diff --git a/deploy/index.md b/deploy/index.md index 9747f03..3de4f32 100644 --- a/deploy/index.md +++ b/deploy/index.md @@ -41,15 +41,31 @@ A CDN deployment of Protomaps has three parts: ## Next steps -* [Deploy PMTiles on Cloudflare.](/deploy/cloudflare) -* [Deploy PMTiles on AWS.](/deploy/aws) -* [Deploy PMTiles with the Caddy web server.](/deploy/server) - -## Comparison - -| feature | static pmtiles | Cloudflare | AWS | [Caddy](/deploy/server#caddy) | `pmtiles serve` | -| - | - | :-| -: | - | - | -| Z/X/Y compatible | | ✅ | ✅ |✅ | ✅ | -| edge caching | | ✅ | ✅ | With CDN | With CDN | -| SSL | ✅ | ✅ | ✅ | ✅ | With reverse proxy | -| scale to zero | ✅ | 5 USD | ✅ | | | +* [Deploy PMTiles on Cloudflare](/deploy/cloudflare) +* [Deploy PMTiles on AWS](/deploy/aws) +* [Deploy PMTiles on Google Cloud (GCP)](/deploy/google-cloud) +* [Deploy PMTiles with the Caddy web server](/deploy/server) + +## Deployment Comparison Chart + +_Cloudflare is recommended for budget minded beginners. AWS is recommended for commercial companies who require a faster map and/or can offset increased marginal cost with monetization._ + +| feature | static pmtiles | Cloudflare | AWS | GCP, Azure | [Caddy](/deploy/server#caddy) | `pmtiles serve` | +| ---------------- | :--------------: | :----------: | :---: | :----------: | :-----------------------------: | ------------------ | +| Z/X/Y compatible | ✖️ | ✅ | ✅ | ✅ | ✅ | ✅ | +| Edge caching | ✖️ | ✅ | ✅ | With CDN | With CDN | With CDN | +| SSL | ✅ | ✅ | ✅ | ✅ | ✅ | With reverse proxy | +| Scale to zero | ✅ | $5 (USD) | ✅ | ✅ | ✖️ | ✖️ | +| Setup effort | 😓 | 😓 | 😓 | 😓😓 | 😓😓 | 😓😓😓 | +| Latency | 🚀 | 🚀 | 🚀🚀🚀 | 🚀🚀🚀 | 🚀🚀 | 🚀🚀🚀 | +| Cost | 💰 | 💰 | 💰💰💰 | 💰💰💰 | 💰💰 | 💰💰 | + +### Feature explanation + +- **Z/X/Y compatible**: Can tiles be requested as standard web mapping zoom, x, y tile coordinates? +- **Edge caching**: Includes easy to configure edge network for content distribution (or manually paired with CDN) to achieve faster latency? +- **SSL**: Supports encrypted link between tile server and client map library? +- **Scale to zero**: Does the serverless function scale to zero cost during periods of low usage? +- **Setup effort**: Developer time to configure complete cloud tile serving solution, less effort 😓 is better than more 😓😓😓 effort +- **Latency**: Speedy maps tiles 🚀🚀🚀 load in ≤ 200 ms in the client for customers, slow tiles 🚀 load ≥ 500 ms +- **Cost**: Total cost to run tile serving system, with 💰 being cheaper at $5 USD and 💰💰💰 more expensive options that including storage egress and/or CDN bandwidth costs to achieve lower latency diff --git a/deploy/server.md b/deploy/server.md index 5865229..3792aa4 100644 --- a/deploy/server.md +++ b/deploy/server.md @@ -5,33 +5,35 @@ outline: deep # Set up a Server -PMTiles has first-class integration with [Caddy](https://caddyserver.com), a production-grade, dependency-free web server with [automatic HTTPS](https://caddyserver.com/docs/quick-starts/https). The Caddy plugin can serve buckets of archives from private S3-compatible storage, Azure, Google Cloud, public HTTP endpoints, and the filesystem. +Provisioning a dedicated server or virtual machine can be a cost-effective and low latency way method of serving PMTiles archives as Z/X/Y tile endpoints. ::: info If you already use a server like nginx or Apache, you can run [`pmtiles serve`](/pmtiles/cli) behind a reverse proxy configuration. ::: -## Installation +## Caddy -Use [Caddy Downloads](https://caddyserver.com/download?package=github.com%2Fprotomaps%2Fgo-pmtiles%2Fcaddy) to download a Caddy build with the pmtiles plugin for your OS and architecture. +PMTiles has first-class integration with [Caddy](https://caddyserver.com), a production-grade, dependency-free web server with [automatic HTTPS](https://caddyserver.com/docs/quick-starts/https). The Caddy plugin can serve buckets of archives from private S3-compatible storage, Azure, Google Cloud, public HTTP endpoints, and the filesystem. -See the Caddy docs for how to [Keep Caddy Running](https://caddyserver.com/docs/running) by installing as a system service. +### Installation -## Credentials +Use [Caddy Downloads](https://caddyserver.com/download?package=github.com%2Fprotomaps%2Fgo-pmtiles%2Fcaddy) to download a Caddy build with the pmtiles plugin for your OS and architecture. -Credentials will be loaded from environment variables by the [gocloud](https://gocloud.dev/howto/blob/) library. -* S3 buckets can specify `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` in Caddy's [unit files](https://caddyserver.com/docs/running#unit-files): +![caddy plugin](server_caddy.png) -```txt{3-4} -... -[Service] -Environment=AWS_ACCESS_KEY_ID=mykey -Environment=AWS_SECRET_ACCESS_KEY=mysecret +Verify that the `pmtiles_proxy` plugin is present in your `caddy` executable: + +```sh +caddy list-modules ... +http.handlers.pmtiles_proxy + + Non-standard modules: 1 ``` +See the Caddy docs for how to [Keep Caddy Running](https://caddyserver.com/docs/running) by installing as a system service. -## Caddyfile +### Caddyfile A minimal configuration for serving a bucket: @@ -45,7 +47,7 @@ localhost:2019 { pmtiles_proxy { bucket https://example.com cache_size 256 - public_hostname https://localhost:2019/tiles + public_url https://localhost:2019/tiles } } } @@ -57,8 +59,19 @@ localhost:2019 { Examples: * `s3://my_bucket?region=auto&endpoint=https://1234.r2.cloudflarestorage.com` * `cache_size`: Cache size in MB for intermediate PMTiles headers and directories. Tile data and JSON metadata are not cached. -* `public_hostname`: The hostname and path that appears in [TileJSON](https://github.com/mapbox/tilejson-spec/tree/master/3.0.0). Required only if you need TileJSON responses. Must be the public hostname as it should appear to the browser, after traversing any proxies or CDNs. +* `public_url`: The base URL and path that appears in [TileJSON](https://github.com/mapbox/tilejson-spec/tree/master/3.0.0). Required only if you need TileJSON responses. Must be the public URL as it should appear to the browser, after traversing any proxies or CDNs. For a production-ready deployment, refer to the Caddy docs on [configuring SSL](https://caddyserver.com/docs/automatic-https#hostname-requirements) and [CORS headers](https://caddyserver.com/docs/caddyfile/directives/header). +### Credentials + +Credentials will be loaded from environment variables by the [gocloud](https://gocloud.dev/howto/blob/) library. +* S3 buckets can specify `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` in Caddy's [unit files](https://caddyserver.com/docs/running#unit-files): +```txt{3-4} +... +[Service] +Environment=AWS_ACCESS_KEY_ID=mykey +Environment=AWS_SECRET_ACCESS_KEY=mysecret +... +``` diff --git a/deploy/server_caddy.png b/deploy/server_caddy.png new file mode 100644 index 0000000..e91a475 Binary files /dev/null and b/deploy/server_caddy.png differ diff --git a/guide/getting-started.md b/guide/getting-started.md index e7e605d..abe1c4a 100644 --- a/guide/getting-started.md +++ b/guide/getting-started.md @@ -50,14 +50,20 @@ pmtiles extract https://build.protomaps.com/{{ dateNoDashes }}.pmtiles my_area.p > **Note:** You can find the bounding box of your own area, using tools, such as [http://bboxfinder.com/](http://bboxfinder.com/#51.830755,4.742883,52.256198,5.552837) +We can also create a subset of the whole planet that is only zoom levels 0 to 6 and ~60 MB: + +```bash-vue +pmtiles extract https://build.protomaps.com/{{ dateNoDashes }}.pmtiles planet_z6.pmtiles --maxzoom=6 +``` + ## 4. View the basemap -[maps.protomaps.com](https://maps.protomaps.com) is a viewer for basemaps. Drag our file `my_area.pmtiles` onto the `Drop Zone` to view the map: +[maps.protomaps.com](https://maps.protomaps.com) is a viewer for basemaps. Drag our file `my_area.pmtiles` or `planet_z6.pmtiles` onto the `Drop Zone` to view the map: ![utrecht image](./utrecht.png) ## Next Steps * Upload your tiles to cloud storage: [Cloud Storage](/pmtiles/cloud-storage) -* Change the appearance or theme of the basemap: [Basemap Styles](/basemaps/styles) +* Change the appearance of the basemap: [Basemap Styles](/basemaps/flavors) * Bring your own datasets: [Creating PMTiles](/pmtiles/create) diff --git a/guide/security-privacy.md b/guide/security-privacy.md new file mode 100644 index 0000000..fd66985 --- /dev/null +++ b/guide/security-privacy.md @@ -0,0 +1,137 @@ +--- +title: Security and Privacy +outline: deep +--- + +# Security and Privacy + +## Applications + +Protomaps is designed for simple, secure and privacy-enabled map publishing, and is especially suited for: + +* Maps for humanitarian operations, adversarial environments or emergency services. Protomaps enables maps to **work 100% offline**, meaning there's less risk of data leaks or compromise. + +* **Public sector**: Protomaps can power mapping applications in city government, using storage and servers already provisioned. It ensures user data is not transmitted to third party map APIs, and can enable [compliance in the European Union.](#gdpr) + +## Checklist + +### Storage buckets + +Verify the **access level of your storage buckets.** + +Hosting PMTiles from a public storage bucket and decoding via [pmtiles.js](/pmtiles/maplibre) is the simplest publishing method, but allows anyone to download your entire tileset. To limit access, use one of the [deployment options](/deploy/) for decoding on the server or in a serverless function. + +### HTTPS + +Ensure that you access your maps over HTTPS instead of plain HTTP. + +Using HTTPS is also required for [HTTP/2](https://developer.mozilla.org/en-US/docs/Glossary/HTTP_2) and 3, which will make map viewing faster by [enabling more requests at a time compared to HTTP 1.1](https://developer.mozilla.org/en-US/docs/Web/HTTP/Connection_management_in_HTTP_1.x#domain_sharding). + +### CORS + +[Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) limits the sites that are allowed to embed your hosted resources, such as PMTiles archives, ZXY tile endpoints and TileJSON. + +Check the [Cloud Storage](/pmtiles/cloud-storage) docs for your platform for how to configure CORS. + +Avoid the `*` wildcard value for `Access-Control-Allow-Origin` for production traffic. + +### Map Resources + +Even if your PMTiles archives or tile endpoints come from your own infrastructure, other resources on a web map may come from an external origin. These include: + + * Map rendering library JavaScript. + + * Map rendering library CSS Stylesheets. + + * For MapLibre GL: Map style JSON, spritesheets, fontstacks, and RTL (right-to-left) text plugins. See [Example Application](#example-application) below. + + * Use Subresource Integrity to ensure that libraries from third parties are not compromised. Example: + +```html + + + + + +
+ + + +``` + +* `maplibre-gl.js`, `maplibre-gl.css` - JavaScript and CSS for the MapLibre GL rendering library. +* `pmtiles.js` - JavaScript for decoding PMTiles archives in the browser. +* `basemaps.js` - JavaScript for creating a MapLibre GL style for a basemap tileset. +* `mapbox-gl-rtl-text.min.js` - MapLibre plugin for supporting right-to-left languages. +* `https://example.com/fonts/{fontstack}/{range}.pbf` - Font glyphs for rendering labels, available at [protomaps/basemaps-assets](https://github.com/protomaps/basemaps-assets). +* `https://example.com/sprites/{version/{flavor_name}` - Sprites for basemap icons, available at [protomaps/basemaps-assets](https://github.com/protomaps/basemaps-assets). + +The URLs for glyphs and sprites must be absolute, in order to load the ressources correctly. This is due to the [behavior of MapLibre](https://github.com/maplibre/maplibre-gl-js/issues/182). diff --git a/package-lock.json b/package-lock.json index 59dc2ff..1f52602 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,41 +5,44 @@ "packages": { "": { "dependencies": { - "maplibre-gl": "^3.4.1", - "pmtiles": "^2.10.0", - "protomaps-themes-base": "^2.0.0-alpha.0", - "vitepress": "^1.0.0-rc.15" + "@protomaps/basemaps": "5.0.0", + "maplibre-gl": "^4.7.1", + "pmtiles": "^4.1.0", + "vitepress": "^1.6.4" }, "devDependencies": { "prettier": "^3.0.3" } }, "node_modules/@algolia/autocomplete-core": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", - "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.7.tgz", + "integrity": "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==", + "license": "MIT", "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", - "@algolia/autocomplete-shared": "1.9.3" + "@algolia/autocomplete-plugin-algolia-insights": "1.17.7", + "@algolia/autocomplete-shared": "1.17.7" } }, "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", - "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.7.tgz", + "integrity": "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==", + "license": "MIT", "dependencies": { - "@algolia/autocomplete-shared": "1.9.3" + "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", - "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.7.tgz", + "integrity": "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==", + "license": "MIT", "dependencies": { - "@algolia/autocomplete-shared": "1.9.3" + "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", @@ -47,133 +50,221 @@ } }, "node_modules/@algolia/autocomplete-shared": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", - "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.7.tgz", + "integrity": "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==", + "license": "MIT", "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, - "node_modules/@algolia/cache-browser-local-storage": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.20.0.tgz", - "integrity": "sha512-uujahcBt4DxduBTvYdwO3sBfHuJvJokiC3BP1+O70fglmE1ShkH8lpXqZBac1rrU3FnNYSUs4pL9lBdTKeRPOQ==", + "node_modules/@algolia/client-abtesting": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.18.0.tgz", + "integrity": "sha512-DLIrAukjsSrdMNNDx1ZTks72o4RH/1kOn8Wx5zZm8nnqFexG+JzY4SANnCNEjnFQPJTTvC+KpgiNW/CP2lumng==", + "license": "MIT", "dependencies": { - "@algolia/cache-common": "4.20.0" + "@algolia/client-common": "5.18.0", + "@algolia/requester-browser-xhr": "5.18.0", + "@algolia/requester-fetch": "5.18.0", + "@algolia/requester-node-http": "5.18.0" + }, + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@algolia/cache-common": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.20.0.tgz", - "integrity": "sha512-vCfxauaZutL3NImzB2G9LjLt36vKAckc6DhMp05An14kVo8F1Yofb6SIl6U3SaEz8pG2QOB9ptwM5c+zGevwIQ==" - }, - "node_modules/@algolia/cache-in-memory": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.20.0.tgz", - "integrity": "sha512-Wm9ak/IaacAZXS4mB3+qF/KCoVSBV6aLgIGFEtQtJwjv64g4ePMapORGmCyulCFwfePaRAtcaTbMcJF+voc/bg==", + "node_modules/@algolia/client-analytics": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.18.0.tgz", + "integrity": "sha512-0VpGG2uQW+h2aejxbG8VbnMCQ9ary9/ot7OASXi6OjE0SRkYQ/+pkW+q09+IScif3pmsVVYggmlMPtAsmYWHng==", + "license": "MIT", "dependencies": { - "@algolia/cache-common": "4.20.0" + "@algolia/client-common": "5.18.0", + "@algolia/requester-browser-xhr": "5.18.0", + "@algolia/requester-fetch": "5.18.0", + "@algolia/requester-node-http": "5.18.0" + }, + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@algolia/client-account": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.20.0.tgz", - "integrity": "sha512-GGToLQvrwo7am4zVkZTnKa72pheQeez/16sURDWm7Seyz+HUxKi3BM6fthVVPUEBhtJ0reyVtuK9ArmnaKl10Q==", - "dependencies": { - "@algolia/client-common": "4.20.0", - "@algolia/client-search": "4.20.0", - "@algolia/transporter": "4.20.0" + "node_modules/@algolia/client-common": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.18.0.tgz", + "integrity": "sha512-X1WMSC+1ve2qlMsemyTF5bIjwipOT+m99Ng1Tyl36ZjQKTa54oajBKE0BrmM8LD8jGdtukAgkUhFoYOaRbMcmQ==", + "license": "MIT", + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@algolia/client-analytics": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.20.0.tgz", - "integrity": "sha512-EIr+PdFMOallRdBTHHdKI3CstslgLORQG7844Mq84ib5oVFRVASuuPmG4bXBgiDbcsMLUeOC6zRVJhv1KWI0ug==", + "node_modules/@algolia/client-insights": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.18.0.tgz", + "integrity": "sha512-FAJRNANUOSs/FgYOJ/Njqp+YTe4TMz2GkeZtfsw1TMiA5mVNRS/nnMpxas9771aJz7KTEWvK9GwqPs0K6RMYWg==", + "license": "MIT", "dependencies": { - "@algolia/client-common": "4.20.0", - "@algolia/client-search": "4.20.0", - "@algolia/requester-common": "4.20.0", - "@algolia/transporter": "4.20.0" + "@algolia/client-common": "5.18.0", + "@algolia/requester-browser-xhr": "5.18.0", + "@algolia/requester-fetch": "5.18.0", + "@algolia/requester-node-http": "5.18.0" + }, + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@algolia/client-common": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.20.0.tgz", - "integrity": "sha512-P3WgMdEss915p+knMMSd/fwiHRHKvDu4DYRrCRaBrsfFw7EQHon+EbRSm4QisS9NYdxbS04kcvNoavVGthyfqQ==", + "node_modules/@algolia/client-personalization": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.18.0.tgz", + "integrity": "sha512-I2dc94Oiwic3SEbrRp8kvTZtYpJjGtg5y5XnqubgnA15AgX59YIY8frKsFG8SOH1n2rIhUClcuDkxYQNXJLg+w==", + "license": "MIT", "dependencies": { - "@algolia/requester-common": "4.20.0", - "@algolia/transporter": "4.20.0" + "@algolia/client-common": "5.18.0", + "@algolia/requester-browser-xhr": "5.18.0", + "@algolia/requester-fetch": "5.18.0", + "@algolia/requester-node-http": "5.18.0" + }, + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@algolia/client-personalization": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.20.0.tgz", - "integrity": "sha512-N9+zx0tWOQsLc3K4PVRDV8GUeOLAY0i445En79Pr3zWB+m67V+n/8w4Kw1C5LlbHDDJcyhMMIlqezh6BEk7xAQ==", + "node_modules/@algolia/client-query-suggestions": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.18.0.tgz", + "integrity": "sha512-x6XKIQgKFTgK/bMasXhghoEjHhmgoP61pFPb9+TaUJ32aKOGc65b12usiGJ9A84yS73UDkXS452NjyP50Knh/g==", + "license": "MIT", "dependencies": { - "@algolia/client-common": "4.20.0", - "@algolia/requester-common": "4.20.0", - "@algolia/transporter": "4.20.0" + "@algolia/client-common": "5.18.0", + "@algolia/requester-browser-xhr": "5.18.0", + "@algolia/requester-fetch": "5.18.0", + "@algolia/requester-node-http": "5.18.0" + }, + "engines": { + "node": ">= 14.0.0" } }, "node_modules/@algolia/client-search": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.20.0.tgz", - "integrity": "sha512-zgwqnMvhWLdpzKTpd3sGmMlr4c+iS7eyyLGiaO51zDZWGMkpgoNVmltkzdBwxOVXz0RsFMznIxB9zuarUv4TZg==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.18.0.tgz", + "integrity": "sha512-qI3LcFsVgtvpsBGR7aNSJYxhsR+Zl46+958ODzg8aCxIcdxiK7QEVLMJMZAR57jGqW0Lg/vrjtuLFDMfSE53qA==", + "license": "MIT", "dependencies": { - "@algolia/client-common": "4.20.0", - "@algolia/requester-common": "4.20.0", - "@algolia/transporter": "4.20.0" + "@algolia/client-common": "5.18.0", + "@algolia/requester-browser-xhr": "5.18.0", + "@algolia/requester-fetch": "5.18.0", + "@algolia/requester-node-http": "5.18.0" + }, + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@algolia/logger-common": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.20.0.tgz", - "integrity": "sha512-xouigCMB5WJYEwvoWW5XDv7Z9f0A8VoXJc3VKwlHJw/je+3p2RcDXfksLI4G4lIVncFUYMZx30tP/rsdlvvzHQ==" + "node_modules/@algolia/ingestion": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.18.0.tgz", + "integrity": "sha512-bGvJg7HnGGm+XWYMDruZXWgMDPVt4yCbBqq8DM6EoaMBK71SYC4WMfIdJaw+ABqttjBhe6aKNRkWf/bbvYOGyw==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.18.0", + "@algolia/requester-browser-xhr": "5.18.0", + "@algolia/requester-fetch": "5.18.0", + "@algolia/requester-node-http": "5.18.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/monitoring": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.18.0.tgz", + "integrity": "sha512-lBssglINIeGIR+8KyzH05NAgAmn1BCrm5D2T6pMtr/8kbTHvvrm1Zvcltc5dKUQEFyyx3J5+MhNc7kfi8LdjVw==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.18.0", + "@algolia/requester-browser-xhr": "5.18.0", + "@algolia/requester-fetch": "5.18.0", + "@algolia/requester-node-http": "5.18.0" + }, + "engines": { + "node": ">= 14.0.0" + } }, - "node_modules/@algolia/logger-console": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.20.0.tgz", - "integrity": "sha512-THlIGG1g/FS63z0StQqDhT6bprUczBI8wnLT3JWvfAQDZX5P6fCg7dG+pIrUBpDIHGszgkqYEqECaKKsdNKOUA==", + "node_modules/@algolia/recommend": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.18.0.tgz", + "integrity": "sha512-uSnkm0cdAuFwdMp4pGT5vHVQ84T6AYpTZ3I0b3k/M3wg4zXDhl3aCiY8NzokEyRLezz/kHLEEcgb/tTTobOYVw==", + "license": "MIT", "dependencies": { - "@algolia/logger-common": "4.20.0" + "@algolia/client-common": "5.18.0", + "@algolia/requester-browser-xhr": "5.18.0", + "@algolia/requester-fetch": "5.18.0", + "@algolia/requester-node-http": "5.18.0" + }, + "engines": { + "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.20.0.tgz", - "integrity": "sha512-HbzoSjcjuUmYOkcHECkVTwAelmvTlgs48N6Owt4FnTOQdwn0b8pdht9eMgishvk8+F8bal354nhx/xOoTfwiAw==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.18.0.tgz", + "integrity": "sha512-1XFjW0C3pV0dS/9zXbV44cKI+QM4ZIz9cpatXpsjRlq6SUCpLID3DZHsXyE6sTb8IhyPaUjk78GEJT8/3hviqg==", + "license": "MIT", "dependencies": { - "@algolia/requester-common": "4.20.0" + "@algolia/client-common": "5.18.0" + }, + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@algolia/requester-common": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.20.0.tgz", - "integrity": "sha512-9h6ye6RY/BkfmeJp7Z8gyyeMrmmWsMOCRBXQDs4mZKKsyVlfIVICpcSibbeYcuUdurLhIlrOUkH3rQEgZzonng==" + "node_modules/@algolia/requester-fetch": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.18.0.tgz", + "integrity": "sha512-0uodeNdAHz1YbzJh6C5xeQ4T6x5WGiUxUq3GOaT/R4njh5t78dq+Rb187elr7KtnjUmETVVuCvmEYaThfTHzNg==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.18.0" + }, + "engines": { + "node": ">= 14.0.0" + } }, "node_modules/@algolia/requester-node-http": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.20.0.tgz", - "integrity": "sha512-ocJ66L60ABSSTRFnCHIEZpNHv6qTxsBwJEPfYaSBsLQodm0F9ptvalFkHMpvj5DfE22oZrcrLbOYM2bdPJRHng==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.18.0.tgz", + "integrity": "sha512-tZCqDrqJ2YE2I5ukCQrYN8oiF6u3JIdCxrtKq+eniuLkjkO78TKRnXrVcKZTmfFJyyDK8q47SfDcHzAA3nHi6w==", + "license": "MIT", "dependencies": { - "@algolia/requester-common": "4.20.0" + "@algolia/client-common": "5.18.0" + }, + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@algolia/transporter": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.20.0.tgz", - "integrity": "sha512-Lsii1pGWOAISbzeyuf+r/GPhvHMPHSPrTDWNcIzOE1SG1inlJHICaVe2ikuoRjcpgxZNU54Jl+if15SUCsaTUg==", - "dependencies": { - "@algolia/cache-common": "4.20.0", - "@algolia/logger-common": "4.20.0", - "@algolia/requester-common": "4.20.0" + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.22.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", - "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.3" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -181,29 +272,45 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/types": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@docsearch/css": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.5.2.tgz", - "integrity": "sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA==" + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.8.2.tgz", + "integrity": "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==", + "license": "MIT" }, "node_modules/@docsearch/js": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.5.2.tgz", - "integrity": "sha512-p1YFTCDflk8ieHgFJYfmyHBki1D61+U9idwrLh+GQQMrBSP3DLGKpy0XUJtPjAOPltcVbqsTjiPFfH7JImjUNg==", + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.8.2.tgz", + "integrity": "sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==", + "license": "MIT", "dependencies": { - "@docsearch/react": "3.5.2", + "@docsearch/react": "3.8.2", "preact": "^10.0.0" } }, "node_modules/@docsearch/react": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.5.2.tgz", - "integrity": "sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng==", + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.8.2.tgz", + "integrity": "sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==", + "license": "MIT", "dependencies": { - "@algolia/autocomplete-core": "1.9.3", - "@algolia/autocomplete-preset-algolia": "1.9.3", - "@docsearch/css": "3.5.2", - "algoliasearch": "^4.19.1" + "@algolia/autocomplete-core": "1.17.7", + "@algolia/autocomplete-preset-algolia": "1.17.7", + "@docsearch/css": "3.8.2", + "algoliasearch": "^5.14.2" }, "peerDependencies": { "@types/react": ">= 16.8.0 < 19.0.0", @@ -226,13 +333,30 @@ } } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], + "license": "MIT", "optional": true, "os": [ "android" @@ -242,12 +366,13 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "android" @@ -257,12 +382,13 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "android" @@ -272,12 +398,13 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -287,12 +414,13 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -302,12 +430,13 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -317,12 +446,13 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -332,12 +462,13 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -347,12 +478,13 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -362,12 +494,13 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -377,12 +510,13 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -392,12 +526,13 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -407,12 +542,13 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -422,12 +558,13 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -437,12 +574,13 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -452,12 +590,13 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -467,12 +606,13 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "netbsd" @@ -482,12 +622,13 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "openbsd" @@ -497,12 +638,13 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "sunos" @@ -512,12 +654,13 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -527,12 +670,13 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -542,12 +686,13 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -556,10 +701,26 @@ "node": ">=12" } }, + "node_modules/@iconify-json/simple-icons": { + "version": "1.2.47", + "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.47.tgz", + "integrity": "sha512-wa/2O7G4sBmwSEWWLh5C+HeY00lVOoWYRKJOYQtk7lAbQrHUReD1ijiGOyTynV1YavxtNueL1CBA1UZmYJfOrQ==", + "license": "CC0-1.0", + "dependencies": { + "@iconify/types": "*" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "license": "MIT" + }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" }, "node_modules/@mapbox/geojson-rewind": { "version": "0.5.2", @@ -594,7 +755,8 @@ "node_modules/@mapbox/unitbezier": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz", - "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==" + "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==", + "license": "BSD-2-Clause" }, "node_modules/@mapbox/vector-tile": { "version": "1.3.1", @@ -613,16 +775,19 @@ } }, "node_modules/@maplibre/maplibre-gl-style-spec": { - "version": "19.3.2", - "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-19.3.2.tgz", - "integrity": "sha512-C2JAk64XUz9v78+bpyTk1zvgjjnDsB8CCjNumyAYdWK2dvdDtILzh1AGBMdS/llX3KaHjGYxAE5wOwfdwq4Pog==", + "version": "20.3.1", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-20.3.1.tgz", + "integrity": "sha512-5ueL4UDitzVtceQ8J4kY+Px3WK+eZTsmGwha3MBKHKqiHvKrjWWwBCIl1K8BuJSc5OFh83uI8IFNoFvQxX2uUw==", + "license": "ISC", "dependencies": { "@mapbox/jsonlint-lines-primitives": "~2.0.2", "@mapbox/unitbezier": "^0.0.1", - "json-stringify-pretty-compact": "^3.0.0", + "json-stringify-pretty-compact": "^4.0.0", "minimist": "^1.2.8", + "quickselect": "^2.0.0", "rw": "^1.3.3", - "sort-object": "^3.0.3" + "sort-object": "^3.0.3", + "tinyqueue": "^3.0.0" }, "bin": { "gl-style-format": "dist/gl-style-format.mjs", @@ -630,215 +795,642 @@ "gl-style-validate": "dist/gl-style-validate.mjs" } }, + "node_modules/@maplibre/maplibre-gl-style-spec/node_modules/quickselect": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", + "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==", + "license": "ISC" + }, + "node_modules/@protomaps/basemaps": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@protomaps/basemaps/-/basemaps-5.0.0.tgz", + "integrity": "sha512-lp+2ktb9gC9jZ/2L2AKvuQt36MNV1lJPOxDHA3IgD09roloxgp6QwXcMyE36ijGKMuKUiYKnmUuT9ouVhNgdLA==", + "license": "BSD-3-Clause" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.0.tgz", + "integrity": "sha512-TnF0md3qWSRDlU96y9+0dd5RNrlXiQUp1K2pK1UpNmjeND+o9ts9Jxv3G6ntagkt8jVh0KAT1VYgU0nCz5gt2w==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.0.tgz", + "integrity": "sha512-L/7oX07eY6ACt2NXDrku1JIPdf9VGV/DI92EjAd8FRDzMMub5hXFpT1OegBqimJh9xy9Vv+nToaVtZp4Ku9SEA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.0.tgz", + "integrity": "sha512-I1ZucWPVS96hjAsMSJiGosHTqMulMynrmTN+Xde5OsLcU5SjE0xylBmQ/DbB2psJ+HasINrJYz8HQpojtAw2eA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.0.tgz", + "integrity": "sha512-CTZ+lHMsTbH1q/XLKzmnJWxl2r/1xdv7cnjwbi5v+95nVA1syikxWLvqur4nDoGDHjC8oNMBGurnQptpuFJHXA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.0.tgz", + "integrity": "sha512-BB8+4OMzk2JiKL5+aK8A0pi9DPB5pkIBZWXr19+grdez9b0VKihvV432uSwuZLO0sI6zCyxak8NO3mZ1yjM1jA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.0.tgz", + "integrity": "sha512-Udz9Uh26uEE6phGMG2++TfpsLK/z4cYJqrIOyVhig/PMoWiZLghpjZUQvsAylsoztbpg0/QmplkDAyyVq0x6Jg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.0.tgz", + "integrity": "sha512-IPSCTzP8GRYzY+siSnggIKrckC2U+kVXoen6eSHRDgU9a4EZCHHWWOiKio1EkieOOk2j6EvZaaHfQUCmt8UJBg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.0.tgz", + "integrity": "sha512-GvHPu0UIDx+ohyS8vTYnwoSVMM5BH3NO+JwQs6GWNCuQVlC5rKxnH2WClTGu3NxiIfhKLai08IKUwn3QbzX1UQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.0.tgz", + "integrity": "sha512-Pnnn/2CAZWcH9GQoj1nnr85Ejh7aNDe5MsEV0xhuFNUPF0SdnutJ7b2muOI5Kx12T0/i2ol5B/tlhMviZQDL3g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.0.tgz", + "integrity": "sha512-AP+DLj4q9FT22ZL43ssA3gizEn7/MfJcZ1BOuyEPqoriuH3a8VRuDddN0MtpUwEtiZL6jc1GY5/eL99hkloQ1Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.0.tgz", + "integrity": "sha512-1+jPFClHmDATqbk0Cwi74KEOymVcs09Vbqe/CTKqLwCP0TeP2CACfnMnjYBs5CJgO20e/4bxFtmbR/9fKE1gug==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.0.tgz", + "integrity": "sha512-Nmt5Us5w2dL8eh7QVyAIDVVwBv4wk8ljrBQe7lWkLaOcwABDaFQ3K4sAAC6IsOdJwaXXW+d85zVaMN+Xl8Co2w==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.0.tgz", + "integrity": "sha512-KGuQ8WGhnq09LR7eOru7P9jfBSYXTMhq6TyavWfmEo+TxvkvuRwOCee5lPIa6HYjblOuFr4GeOxSE0c8iyw2Fg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.0.tgz", + "integrity": "sha512-lSQtvrYIONme7a4gbf4O9d3zbZat3/5covIeoqk27ZIkTgBeL/67x+wq2bZfpLjkqQQp5SjBPQ/n0sg8iArzTg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.0.tgz", + "integrity": "sha512-qh0ussrXBwnF4L07M9t1+jpHRhiGSae+wpNQDbmlXHXciT7pqpZ5zpk4dyGZPtDGB2l2clDiufE16BufXPGRWQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.0.tgz", + "integrity": "sha512-YEABzSaRS7+v14yw6MVBZoMqLoUyTX1/sJoGeC0euvgMrzvw0i+jHo4keDZgYeOblfwdseVAf6ylxWSvcBAKTA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.0.tgz", + "integrity": "sha512-jA4+oxG7QTTtSQxwSHzFVwShcppHO2DpkbAM59pfD5WMG/da79yQaeBtXAfGTI+ciUx8hqK3RF3H2KWByITXtQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.0.tgz", + "integrity": "sha512-4TQbLoAQVu9uE+cvh47JnjRZylXVdRCoOkRSVF2Rr2T0U1YwphGRjR0sHyRPEt95y3ETT4YFTTzQPq1O4bcjmw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.0.tgz", + "integrity": "sha512-GsFvcTZ7Yj9k94Qm0qgav7pxmQ7lQDR9NjoelRaxeV1UF6JSDfanR/2tHZ8hS7Ps4KPIVf5AElYPRPmN/Q0ZkQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-2.5.0.tgz", + "integrity": "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==", + "license": "MIT", + "dependencies": { + "@shikijs/engine-javascript": "2.5.0", + "@shikijs/engine-oniguruma": "2.5.0", + "@shikijs/types": "2.5.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.4" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-2.5.0.tgz", + "integrity": "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "2.5.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^3.1.0" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-2.5.0.tgz", + "integrity": "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "2.5.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-2.5.0.tgz", + "integrity": "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "2.5.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-2.5.0.tgz", + "integrity": "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "2.5.0" + } + }, + "node_modules/@shikijs/transformers": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-2.5.0.tgz", + "integrity": "sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==", + "license": "MIT", + "dependencies": { + "@shikijs/core": "2.5.0", + "@shikijs/types": "2.5.0" + } + }, + "node_modules/@shikijs/types": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-2.5.0.tgz", + "integrity": "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==", + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "license": "MIT" + }, "node_modules/@types/geojson": { - "version": "7946.0.11", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.11.tgz", - "integrity": "sha512-L7A0AINMXQpVwxHJ4jxD6/XjZ4NDufaRlUJHjNIFKYUFBH1SvOW+neaqb0VTRSLW5suSrSu19ObFEFnfNcr+qg==" + "version": "7946.0.14", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==", + "license": "MIT" + }, + "node_modules/@types/geojson-vt": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@types/geojson-vt/-/geojson-vt-3.2.5.tgz", + "integrity": "sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==", + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "license": "MIT" }, "node_modules/@types/mapbox__point-geometry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.2.tgz", - "integrity": "sha512-D0lgCq+3VWV85ey1MZVkE8ZveyuvW5VAfuahVTQRpXFQTxw03SuIf1/K4UQ87MMIXVKzpFjXFiFMZzLj2kU+iA==" + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.4.tgz", + "integrity": "sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==", + "license": "MIT" }, "node_modules/@types/mapbox__vector-tile": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.1.tgz", - "integrity": "sha512-RpwGE57xM4a/YCH6XWzfcPVRPAu/jiCll0bEGRn6a4iubN2k4xZizskQoRj8fuXyo9BpI7F3bwz3uxs0pWbGNw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.4.tgz", + "integrity": "sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==", + "license": "MIT", "dependencies": { "@types/geojson": "*", "@types/mapbox__point-geometry": "*", "@types/pbf": "*" } }, + "node_modules/@types/markdown-it": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", + "license": "MIT", + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "license": "MIT" + }, "node_modules/@types/pbf": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.3.tgz", - "integrity": "sha512-hw6bDMjvm+QTvEC+pRLpnTknQXoPu8Fnf+A+zX9HB7j/7RfYajFSbdukabo3adPwvvEHhIMafQl0R0Tpej7clQ==" + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz", + "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==", + "license": "MIT" }, "node_modules/@types/supercluster": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.1.tgz", - "integrity": "sha512-dNK02GO1UApgo+1KpY4jOfm3uWb2eBCMB/VMM2y8cMoF49FiqVVcOawEg19wxYcaX7SvEs370incOuFtFGrVLg==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz", + "integrity": "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==", + "license": "MIT", "dependencies": { "@types/geojson": "*" } }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, "node_modules/@types/web-bluetooth": { - "version": "0.0.17", - "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.17.tgz", - "integrity": "sha512-4p9vcSmxAayx72yn70joFoL44c9MO/0+iVEBIQXe3v2h2SiAsEIo/G5v6ObFWvNKRFjbrVadNf9LqEEZeQPzdA==" + "version": "0.0.21", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz", + "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.1.tgz", + "integrity": "sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==", + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0", + "vue": "^3.2.25" + } }, "node_modules/@vue/compiler-core": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz", - "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz", + "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==", + "license": "MIT", "dependencies": { - "@babel/parser": "^7.21.3", - "@vue/shared": "3.3.4", + "@babel/parser": "^7.25.3", + "@vue/shared": "3.5.13", + "entities": "^4.5.0", "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz", - "integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz", + "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==", + "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.3.4", - "@vue/shared": "3.3.4" + "@vue/compiler-core": "3.5.13", + "@vue/shared": "3.5.13" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz", - "integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==", - "dependencies": { - "@babel/parser": "^7.20.15", - "@vue/compiler-core": "3.3.4", - "@vue/compiler-dom": "3.3.4", - "@vue/compiler-ssr": "3.3.4", - "@vue/reactivity-transform": "3.3.4", - "@vue/shared": "3.3.4", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz", + "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/compiler-core": "3.5.13", + "@vue/compiler-dom": "3.5.13", + "@vue/compiler-ssr": "3.5.13", + "@vue/shared": "3.5.13", "estree-walker": "^2.0.2", - "magic-string": "^0.30.0", - "postcss": "^8.1.10", - "source-map-js": "^1.0.2" + "magic-string": "^0.30.11", + "postcss": "^8.4.48", + "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz", - "integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz", + "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==", + "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.3.4", - "@vue/shared": "3.3.4" + "@vue/compiler-dom": "3.5.13", + "@vue/shared": "3.5.13" } }, "node_modules/@vue/devtools-api": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz", - "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==" + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.7.tgz", + "integrity": "sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==", + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.7.7" + } }, - "node_modules/@vue/reactivity": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz", - "integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==", + "node_modules/@vue/devtools-kit": { + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.7.tgz", + "integrity": "sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==", + "license": "MIT", "dependencies": { - "@vue/shared": "3.3.4" + "@vue/devtools-shared": "^7.7.7", + "birpc": "^2.3.0", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.2" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.7.tgz", + "integrity": "sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==", + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" } }, - "node_modules/@vue/reactivity-transform": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz", - "integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==", + "node_modules/@vue/reactivity": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.13.tgz", + "integrity": "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==", + "license": "MIT", "dependencies": { - "@babel/parser": "^7.20.15", - "@vue/compiler-core": "3.3.4", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.0" + "@vue/shared": "3.5.13" } }, "node_modules/@vue/runtime-core": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.4.tgz", - "integrity": "sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.13.tgz", + "integrity": "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==", + "license": "MIT", "dependencies": { - "@vue/reactivity": "3.3.4", - "@vue/shared": "3.3.4" + "@vue/reactivity": "3.5.13", + "@vue/shared": "3.5.13" } }, "node_modules/@vue/runtime-dom": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz", - "integrity": "sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz", + "integrity": "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==", + "license": "MIT", "dependencies": { - "@vue/runtime-core": "3.3.4", - "@vue/shared": "3.3.4", - "csstype": "^3.1.1" + "@vue/reactivity": "3.5.13", + "@vue/runtime-core": "3.5.13", + "@vue/shared": "3.5.13", + "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.4.tgz", - "integrity": "sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.13.tgz", + "integrity": "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==", + "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.3.4", - "@vue/shared": "3.3.4" + "@vue/compiler-ssr": "3.5.13", + "@vue/shared": "3.5.13" }, "peerDependencies": { - "vue": "3.3.4" + "vue": "3.5.13" } }, "node_modules/@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz", + "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==", + "license": "MIT" }, "node_modules/@vueuse/core": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.4.1.tgz", - "integrity": "sha512-DkHIfMIoSIBjMgRRvdIvxsyboRZQmImofLyOHADqiVbQVilP8VVHDhBX2ZqoItOgu7dWa8oXiNnScOdPLhdEXg==", + "version": "12.8.2", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.8.2.tgz", + "integrity": "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==", + "license": "MIT", "dependencies": { - "@types/web-bluetooth": "^0.0.17", - "@vueuse/metadata": "10.4.1", - "@vueuse/shared": "10.4.1", - "vue-demi": ">=0.14.5" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/core/node_modules/vue-demi": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", - "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" + "@types/web-bluetooth": "^0.0.21", + "@vueuse/metadata": "12.8.2", + "@vueuse/shared": "12.8.2", + "vue": "^3.5.13" }, "funding": { "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } } }, "node_modules/@vueuse/integrations": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-10.4.1.tgz", - "integrity": "sha512-uRBPyG5Lxoh1A/J+boiioPT3ELEAPEo4t8W6Mr4yTKIQBeW/FcbsotZNPr4k9uz+3QEksMmflWloS9wCnypM7g==", + "version": "12.8.2", + "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-12.8.2.tgz", + "integrity": "sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==", + "license": "MIT", "dependencies": { - "@vueuse/core": "10.4.1", - "@vueuse/shared": "10.4.1", - "vue-demi": ">=0.14.5" + "@vueuse/core": "12.8.2", + "@vueuse/shared": "12.8.2", + "vue": "^3.5.13" }, "funding": { "url": "https://github.com/sponsors/antfu" }, "peerDependencies": { - "async-validator": "*", - "axios": "*", - "change-case": "*", - "drauu": "*", - "focus-trap": "*", - "fuse.js": "*", - "idb-keyval": "*", - "jwt-decode": "*", - "nprogress": "*", - "qrcode": "*", - "sortablejs": "*", - "universal-cookie": "*" + "async-validator": "^4", + "axios": "^1", + "change-case": "^5", + "drauu": "^0.4", + "focus-trap": "^7", + "fuse.js": "^7", + "idb-keyval": "^6", + "jwt-decode": "^4", + "nprogress": "^0.2", + "qrcode": "^1.5", + "sortablejs": "^1", + "universal-cookie": "^7" }, "peerDependenciesMeta": { "async-validator": { @@ -879,105 +1471,56 @@ } } }, - "node_modules/@vueuse/integrations/node_modules/vue-demi": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", - "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, "node_modules/@vueuse/metadata": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.4.1.tgz", - "integrity": "sha512-2Sc8X+iVzeuMGHr6O2j4gv/zxvQGGOYETYXEc41h0iZXIRnRbJZGmY/QP8dvzqUelf8vg0p/yEA5VpCEu+WpZg==", + "version": "12.8.2", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.8.2.tgz", + "integrity": "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/shared": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.4.1.tgz", - "integrity": "sha512-vz5hbAM4qA0lDKmcr2y3pPdU+2EVw/yzfRsBdu+6+USGa4PxqSQRYIUC9/NcT06y+ZgaTsyURw2I9qOFaaXHAg==", + "version": "12.8.2", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.8.2.tgz", + "integrity": "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==", + "license": "MIT", "dependencies": { - "vue-demi": ">=0.14.5" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/shared/node_modules/vue-demi": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", - "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" + "vue": "^3.5.13" }, "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } + "url": "https://github.com/sponsors/antfu" } }, "node_modules/algoliasearch": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.20.0.tgz", - "integrity": "sha512-y+UHEjnOItoNy0bYO+WWmLWBlPwDjKHW6mNHrPi0NkuhpQOOEbrkwQH/wgKFDLh7qlKjzoKeiRtlpewDPDG23g==", - "dependencies": { - "@algolia/cache-browser-local-storage": "4.20.0", - "@algolia/cache-common": "4.20.0", - "@algolia/cache-in-memory": "4.20.0", - "@algolia/client-account": "4.20.0", - "@algolia/client-analytics": "4.20.0", - "@algolia/client-common": "4.20.0", - "@algolia/client-personalization": "4.20.0", - "@algolia/client-search": "4.20.0", - "@algolia/logger-common": "4.20.0", - "@algolia/logger-console": "4.20.0", - "@algolia/requester-browser-xhr": "4.20.0", - "@algolia/requester-common": "4.20.0", - "@algolia/requester-node-http": "4.20.0", - "@algolia/transporter": "4.20.0" - } - }, - "node_modules/ansi-sequence-parser": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", - "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==" + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.18.0.tgz", + "integrity": "sha512-/tfpK2A4FpS0o+S78o3YSdlqXr0MavJIDlFK3XZrlXLy7vaRXJvW5jYg3v5e/wCaF8y0IpMjkYLhoV6QqfpOgw==", + "license": "MIT", + "dependencies": { + "@algolia/client-abtesting": "5.18.0", + "@algolia/client-analytics": "5.18.0", + "@algolia/client-common": "5.18.0", + "@algolia/client-insights": "5.18.0", + "@algolia/client-personalization": "5.18.0", + "@algolia/client-query-suggestions": "5.18.0", + "@algolia/client-search": "5.18.0", + "@algolia/ingestion": "1.18.0", + "@algolia/monitoring": "1.18.0", + "@algolia/recommend": "5.18.0", + "@algolia/requester-browser-xhr": "5.18.0", + "@algolia/requester-fetch": "5.18.0", + "@algolia/requester-node-http": "5.18.0" + }, + "engines": { + "node": ">= 14.0.0" + } }, "node_modules/arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -986,14 +1529,25 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/birpc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.5.0.tgz", + "integrity": "sha512-VSWO/W6nNQdyP520F1mhf+Lc2f8pjGQOtoHHm7Ze8Go1kX7akpVIrtTa0fn+HB0QJEDVacl6aO08YE0PgXfdnQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/bytewise": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz", "integrity": "sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ==", + "license": "MIT", "dependencies": { "bytewise-core": "^1.2.2", "typewise": "^1.0.3" @@ -1003,25 +1557,124 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz", "integrity": "sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA==", + "license": "MIT", "dependencies": { "typewise-core": "^1.2" } }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/copy-anything": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", + "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", + "license": "MIT", + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, "node_modules/earcut": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", - "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.0.tgz", + "integrity": "sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg==", + "license": "ISC" + }, + "node_modules/emoji-regex-xs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz", + "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==", + "license": "MIT" + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } }, "node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -1029,39 +1682,42 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" }, "node_modules/extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", "dependencies": { "is-extendable": "^0.1.0" }, @@ -1070,14 +1726,16 @@ } }, "node_modules/fflate": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.1.tgz", - "integrity": "sha512-/exOvEuc+/iaUm105QIiOt4LpBdMTWsXxqR0HDF35vx3fmaKzw7354gTilCh5rkzEt8WYyG//ku3h3nRmd7CHQ==" + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "license": "MIT" }, "node_modules/focus-trap": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.2.tgz", - "integrity": "sha512-p6vGNNWLDGwJCiEjkSK6oERj/hEyI9ITsSwIUICBoKLlWiTWXJRfQibCwcoi50rTZdbi87qDtUlMCmQwsGSgPw==", + "version": "7.6.5", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.5.tgz", + "integrity": "sha512-7Ke1jyybbbPZyZXFxEftUtxFGLMpE2n6A+z//m4CRDlj0hW+o3iYSmh8nFlYMurOiJVDmJRilUQtJr08KfIxlg==", + "license": "MIT", "dependencies": { "tabbable": "^6.2.0" } @@ -1087,6 +1745,7 @@ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -1096,9 +1755,10 @@ } }, "node_modules/geojson-vt": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz", - "integrity": "sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-4.0.2.tgz", + "integrity": "sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==", + "license": "ISC" }, "node_modules/get-stream": { "version": "6.0.1", @@ -1115,6 +1775,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1125,16 +1786,69 @@ "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==" }, "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-4.0.0.tgz", + "integrity": "sha512-w0Uf9Y9/nyHinEk5vMJKRie+wa4kR5hmDbEhGGds/kG1PwGLLHKRoNMeJOyCQjjBkANlnScqgzcFwGHgmgLkVA==", + "license": "MIT", "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" + "ini": "^4.1.3", + "kind-of": "^6.0.3", + "which": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=16" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "license": "MIT" + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, "node_modules/ieee754": { @@ -1157,14 +1871,19 @@ ] }, "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, "node_modules/is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1173,6 +1892,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -1180,28 +1900,41 @@ "node": ">=0.10.0" } }, + "node_modules/is-what": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", + "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", + "license": "MIT", + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "license": "ISC", + "engines": { + "node": ">=16" + } }, "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/json-stringify-pretty-compact": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-3.0.0.tgz", - "integrity": "sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA==" - }, - "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz", + "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==", + "license": "MIT" }, "node_modules/kdbush": { "version": "4.0.2", @@ -1212,25 +1945,25 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/maplibre-gl": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-3.4.1.tgz", - "integrity": "sha512-RPcdaiZ52G3X+PaHQxqQ1d4I8iTIPRl4OXhPU/3o37kDf+ImLXpUVZj4p0qBCGm71n79daVzaCMG9QxfSSQbnQ==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.7.1.tgz", + "integrity": "sha512-lgL7XpIwsgICiL82ITplfS7IGwrB1OJIw/pCvprDp2dhmSSEBgmPzYRvwYYYvJGJD7fxUv1Tvpih4nZ6VrLuaA==", + "license": "BSD-3-Clause", "dependencies": { "@mapbox/geojson-rewind": "^0.5.2", "@mapbox/jsonlint-lines-primitives": "^2.0.2", @@ -1239,23 +1972,24 @@ "@mapbox/unitbezier": "^0.0.1", "@mapbox/vector-tile": "^1.3.1", "@mapbox/whoots-js": "^3.1.0", - "@maplibre/maplibre-gl-style-spec": "^19.3.2", - "@types/geojson": "^7946.0.11", - "@types/mapbox__point-geometry": "^0.1.2", - "@types/mapbox__vector-tile": "^1.3.1", - "@types/pbf": "^3.0.3", - "@types/supercluster": "^7.1.1", - "earcut": "^2.2.4", - "geojson-vt": "^3.2.1", + "@maplibre/maplibre-gl-style-spec": "^20.3.1", + "@types/geojson": "^7946.0.14", + "@types/geojson-vt": "3.2.5", + "@types/mapbox__point-geometry": "^0.1.4", + "@types/mapbox__vector-tile": "^1.3.4", + "@types/pbf": "^3.0.5", + "@types/supercluster": "^7.1.3", + "earcut": "^3.0.0", + "geojson-vt": "^4.0.2", "gl-matrix": "^3.4.3", - "global-prefix": "^3.0.0", + "global-prefix": "^4.0.0", "kdbush": "^4.0.2", "murmurhash-js": "^1.0.0", - "pbf": "^3.2.1", + "pbf": "^3.3.0", "potpack": "^2.0.0", - "quickselect": "^2.0.0", + "quickselect": "^3.0.0", "supercluster": "^8.0.1", - "tinyqueue": "^2.0.3", + "tinyqueue": "^3.0.0", "vt-pbf": "^3.1.3" }, "engines": { @@ -1271,6 +2005,116 @@ "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==" }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", @@ -1280,9 +2124,16 @@ } }, "node_modules/minisearch": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-6.1.0.tgz", - "integrity": "sha512-PNxA/X8pWk+TiqPbsoIYH0GQ5Di7m6326/lwU/S4mlo4wGQddIcf/V//1f9TB0V4j59b57b+HZxt8h3iMROGvg==" + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.1.1.tgz", + "integrity": "sha512-b3YZEYCEH4EdCAtYP7OlDyx7FdPwNzuNwLQ34SfJpM9dlbBZzeXndGavTrC+VCiRWomL21SWfMc6SCKO/U2ZNw==", + "license": "MIT" + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "license": "MIT" }, "node_modules/murmurhash-js": { "version": "1.0.0", @@ -1290,15 +2141,16 @@ "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==" }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -1306,10 +2158,22 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/oniguruma-to-es": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-3.1.1.tgz", + "integrity": "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==", + "license": "MIT", + "dependencies": { + "emoji-regex-xs": "^1.0.0", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2" + } + }, "node_modules/pbf": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz", - "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.3.0.tgz", + "integrity": "sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==", + "license": "BSD-3-Clause", "dependencies": { "ieee754": "^1.1.12", "resolve-protobuf-schema": "^2.1.0" @@ -1318,23 +2182,31 @@ "pbf": "bin/pbf" } }, - "node_modules/picocolors": { + "node_modules/perfect-debounce": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" }, "node_modules/pmtiles": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/pmtiles/-/pmtiles-2.10.0.tgz", - "integrity": "sha512-X+s6JyperpcAkKwv55MKx72ckOUB0ZjcfK4929iM0SS0MkLydEi2FSW1E8YTE1E2XaZ2TVk/MIUrbsZuXV7K2g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/pmtiles/-/pmtiles-4.1.0.tgz", + "integrity": "sha512-wymKYI61y3yI/iTzYHW18l6ViYBnF7TXbFnXb9q7RcWqkQ2EfgQVDzEIc5lImd3aAVkxu2tuWaoYhokov6N9VA==", + "license": "BSD-3-Clause", "dependencies": { - "fflate": "^0.8.0" + "fflate": "^0.8.2" } }, "node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "funding": [ { "type": "opencollective", @@ -1349,10 +2221,11 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -1364,9 +2237,10 @@ "integrity": "sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw==" }, "node_modules/preact": { - "version": "10.17.1", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.17.1.tgz", - "integrity": "sha512-X9BODrvQ4Ekwv9GURm9AKAGaomqXmip7NQTZgY7gcNmr7XE83adOMJvd3N42id1tMFU7ojiynRsYnY6/BRFxLA==", + "version": "10.25.3", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.25.3.tgz", + "integrity": "sha512-dzQmIFtM970z+fP9ziQ3yG4e3ULIbwZzJ734vaMVUTaKQ2+Ru1Ou/gjshOYVHCcd1rpAelC6ngjvjDXph98unQ==", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -1387,20 +2261,50 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/protocol-buffers-schema": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" }, - "node_modules/protomaps-themes-base": { - "version": "2.0.0-alpha.0", - "resolved": "https://registry.npmjs.org/protomaps-themes-base/-/protomaps-themes-base-2.0.0-alpha.0.tgz", - "integrity": "sha512-/Hqtwu2fVEcyrbimfo0eV6zb1QE+BeOnOBvKlrWRSWM0f745qJ7sBfqFVVoeMu7aFjDSkeW+j+g+spDhPvdGdQ==" - }, "node_modules/quickselect": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", - "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", + "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", + "license": "ISC" + }, + "node_modules/regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.0.1.tgz", + "integrity": "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "license": "MIT" }, "node_modules/resolve-protobuf-schema": { "version": "2.1.0", @@ -1410,36 +2314,68 @@ "protocol-buffers-schema": "^3.3.1" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, "node_modules/rollup": { - "version": "3.29.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.2.tgz", - "integrity": "sha512-CJouHoZ27v6siztc21eEQGo0kIcE5D1gVPA571ez0mMYb25LGYGKnVNXpEj5MGlepmDWGXNjDB5q7uNiPHC11A==", + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.29.0.tgz", + "integrity": "sha512-pdftUn12oB9Qlka+Vpyc39R28D4NsP9Sz6neepSrekofJmWzPD1sxcSO9hEOxFF8+7Kz3sHvwSkkRREI28M1/w==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14.18.0", + "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.29.0", + "@rollup/rollup-android-arm64": "4.29.0", + "@rollup/rollup-darwin-arm64": "4.29.0", + "@rollup/rollup-darwin-x64": "4.29.0", + "@rollup/rollup-freebsd-arm64": "4.29.0", + "@rollup/rollup-freebsd-x64": "4.29.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.29.0", + "@rollup/rollup-linux-arm-musleabihf": "4.29.0", + "@rollup/rollup-linux-arm64-gnu": "4.29.0", + "@rollup/rollup-linux-arm64-musl": "4.29.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.29.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.29.0", + "@rollup/rollup-linux-riscv64-gnu": "4.29.0", + "@rollup/rollup-linux-s390x-gnu": "4.29.0", + "@rollup/rollup-linux-x64-gnu": "4.29.0", + "@rollup/rollup-linux-x64-musl": "4.29.0", + "@rollup/rollup-win32-arm64-msvc": "4.29.0", + "@rollup/rollup-win32-ia32-msvc": "4.29.0", + "@rollup/rollup-win32-x64-msvc": "4.29.0", "fsevents": "~2.3.2" } }, "node_modules/rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" }, "node_modules/search-insights": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.8.2.tgz", - "integrity": "sha512-PxA9M5Q2bpBelVvJ3oDZR8nuY00Z6qwOxL53wNpgzV28M/D6u9WUbImDckjLSILBF8F1hn/mgyuUaOPtjow4Qw==", + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", + "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", + "license": "MIT", "peer": true }, "node_modules/set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "license": "MIT", "dependencies": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -1451,20 +2387,26 @@ } }, "node_modules/shiki": { - "version": "0.14.4", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.4.tgz", - "integrity": "sha512-IXCRip2IQzKwxArNNq1S+On4KPML3Yyn8Zzs/xRgcgOWIr8ntIK3IKzjFPfjy/7kt9ZMjc+FItfqHRBg8b6tNQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-2.5.0.tgz", + "integrity": "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==", + "license": "MIT", "dependencies": { - "ansi-sequence-parser": "^1.1.0", - "jsonc-parser": "^3.2.0", - "vscode-oniguruma": "^1.7.0", - "vscode-textmate": "^8.0.0" + "@shikijs/core": "2.5.0", + "@shikijs/engine-javascript": "2.5.0", + "@shikijs/engine-oniguruma": "2.5.0", + "@shikijs/langs": "2.5.0", + "@shikijs/themes": "2.5.0", + "@shikijs/types": "2.5.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" } }, "node_modules/sort-asc": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/sort-asc/-/sort-asc-0.2.0.tgz", "integrity": "sha512-umMGhjPeHAI6YjABoSTrFp2zaBtXBej1a0yKkuMUyjjqu6FJsTF+JYwCswWDg+zJfk/5npWUUbd33HH/WLzpaA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1473,6 +2415,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/sort-desc/-/sort-desc-0.2.0.tgz", "integrity": "sha512-NqZqyvL4VPW+RAxxXnB8gvE1kyikh8+pR+T+CXLksVRN9eiQqkQlPwqWYU0mF9Jm7UnctShlxLyAt1CaBOTL1w==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1481,6 +2424,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/sort-object/-/sort-object-3.0.3.tgz", "integrity": "sha512-nK7WOY8jik6zaG9CRwZTaD5O7ETWDLZYMM12pqY8htll+7dYeqGfEUPcUBHOpSJg2vJOrvFIY2Dl5cX2ih1hAQ==", + "license": "MIT", "dependencies": { "bytewise": "^1.1.0", "get-value": "^2.0.2", @@ -1494,9 +2438,29 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -1505,6 +2469,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "license": "MIT", "dependencies": { "extend-shallow": "^3.0.0" }, @@ -1516,6 +2481,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "license": "MIT", "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -1528,6 +2494,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4" }, @@ -1535,6 +2502,20 @@ "node": ">=0.10.0" } }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/supercluster": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", @@ -1543,20 +2524,45 @@ "kdbush": "^4.0.2" } }, + "node_modules/superjson": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz", + "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==", + "license": "MIT", + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/tabbable": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", - "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "license": "MIT" }, "node_modules/tinyqueue": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", - "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", + "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", + "license": "ISC" + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, "node_modules/typewise": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz", "integrity": "sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==", + "license": "MIT", "dependencies": { "typewise-core": "^1.2.0" } @@ -1564,12 +2570,14 @@ "node_modules/typewise-core": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz", - "integrity": "sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg==" + "integrity": "sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg==", + "license": "MIT" }, "node_modules/union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "license": "MIT", "dependencies": { "arr-union": "^3.1.0", "get-value": "^2.0.6", @@ -1580,32 +2588,130 @@ "node": ">=0.10.0" } }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vite": { - "version": "4.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", - "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", + "version": "5.4.20", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.20.tgz", + "integrity": "sha512-j3lYzGC3P+B5Yfy/pfKNgVEg4+UtcIJcVRt2cDjIOmhLourAqPqf8P7acgxeiSgUB7E3p2P8/3gNIgDLpwzs4g==", + "license": "MIT", "dependencies": { - "esbuild": "^0.18.10", - "postcss": "^8.4.27", - "rollup": "^3.27.1" + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^18.0.0 || >=20.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { - "fsevents": "~2.3.2" + "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": ">= 14", + "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" @@ -1623,6 +2729,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, @@ -1635,44 +2744,46 @@ } }, "node_modules/vitepress": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.0.0-rc.15.tgz", - "integrity": "sha512-5criiHoEibkT/du7t6wQ2xQVsuTNuirQZbMAi0M9Hp0YzJoJvEX68Ej9p2PtNC84bYb/CxAh5QkMtMutk03lHw==", - "dependencies": { - "@docsearch/css": "^3.5.2", - "@docsearch/js": "^3.5.2", - "@vue/devtools-api": "^6.5.0", - "@vueuse/core": "^10.4.1", - "@vueuse/integrations": "^10.4.1", - "focus-trap": "^7.5.2", + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.6.4.tgz", + "integrity": "sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg==", + "license": "MIT", + "dependencies": { + "@docsearch/css": "3.8.2", + "@docsearch/js": "3.8.2", + "@iconify-json/simple-icons": "^1.2.21", + "@shikijs/core": "^2.1.0", + "@shikijs/transformers": "^2.1.0", + "@shikijs/types": "^2.1.0", + "@types/markdown-it": "^14.1.2", + "@vitejs/plugin-vue": "^5.2.1", + "@vue/devtools-api": "^7.7.0", + "@vue/shared": "^3.5.13", + "@vueuse/core": "^12.4.0", + "@vueuse/integrations": "^12.4.0", + "focus-trap": "^7.6.4", "mark.js": "8.11.1", - "minisearch": "^6.1.0", - "shiki": "^0.14.4", - "vite": "^4.4.9", - "vue": "^3.3.4" + "minisearch": "^7.1.1", + "shiki": "^2.1.0", + "vite": "^5.4.14", + "vue": "^3.5.13" }, "bin": { "vitepress": "bin/vitepress.js" }, "peerDependencies": { - "markdown-it-mathjax3": "^4.3.2" + "markdown-it-mathjax3": "^4", + "postcss": "^8" }, "peerDependenciesMeta": { "markdown-it-mathjax3": { "optional": true + }, + "postcss": { + "optional": true } } }, - "node_modules/vscode-oniguruma": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", - "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==" - }, - "node_modules/vscode-textmate": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", - "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==" - }, "node_modules/vt-pbf": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz", @@ -1684,26 +2795,49 @@ } }, "node_modules/vue": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz", - "integrity": "sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.13.tgz", + "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==", + "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.3.4", - "@vue/compiler-sfc": "3.3.4", - "@vue/runtime-dom": "3.3.4", - "@vue/server-renderer": "3.3.4", - "@vue/shared": "3.3.4" + "@vue/compiler-dom": "3.5.13", + "@vue/compiler-sfc": "3.5.13", + "@vue/runtime-dom": "3.5.13", + "@vue/server-renderer": "3.5.13", + "@vue/shared": "3.5.13" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "license": "ISC", "dependencies": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" }, "bin": { - "which": "bin/which" + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } } } diff --git a/package.json b/package.json index 9821068..d6df596 100644 --- a/package.json +++ b/package.json @@ -7,10 +7,10 @@ "prettier-check": "prettier --check components" }, "dependencies": { - "maplibre-gl": "^3.4.1", - "pmtiles": "^2.10.0", - "protomaps-themes-base": "^2.0.0-alpha.0", - "vitepress": "^1.0.0-rc.15" + "maplibre-gl": "^4.7.1", + "pmtiles": "^4.1.0", + "@protomaps/basemaps": "5.0.0", + "vitepress": "^1.6.4" }, "devDependencies": { "prettier": "^3.0.3" diff --git a/pmtiles/cli.md b/pmtiles/cli.md index 9e4820f..f82d98f 100644 --- a/pmtiles/cli.md +++ b/pmtiles/cli.md @@ -5,37 +5,93 @@ outline: deep # pmtiles CLI +## Installation + +`pmtiles` is a single binary with no external dependencies. + +The source code is on [GitHub at protomaps/go-pmtiles](https://github.com/protomaps/go-pmtiles). + +To download, see [Releases on GitHub](https://github.com/protomaps/go-pmtiles/releases) for your OS and architecture. + +An official Docker Hub image is available at [protomaps/go-pmtiles](https://hub.docker.com/repository/docker/protomaps/go-pmtiles/general). + ## CLI Overview -### Buckets +### Local archives -:::warning -This section is under construction. -::: +The CLI works with local tilesets on disk, for example: + +```sh +pmtiles show test.pmtiles +``` ### Remote archives -:::warning -This section is under construction. +However, `pmtiles` can also work with remote HTTP archives and tilesets on cloud storage, even in private buckets. + +```sh +pmtiles show https://r2-public.protomaps.com/protomaps-sample-datasets/cb_2018_us_zcta510_500k.pmtiles +``` + +`pmtiles` uses the [go-cloud](https://gocloud.dev/howto/blob/) library for connecting and authenticating to cloud storage. + +Commands for S3, Azure Blob and Google Cloud Storage: + +:::info +Commands that uses URL characters like `?` and `&`, should be escaped by a backslash `\` in your shell. +::: + +```sh +pmtiles show test.pmtiles --bucket=s3://BUCKET_NAME +pmtiles show test.pmtiles --bucket=azblob://CONTAINER_NAME?storage_account=ACCOUNT +pmtiles show test.pmtiles --bucket=gs://BUCKET_NAME +``` + +For S3-compatible blob storage (Minio, Cloudflare R2, etc) outside of AWS: + +```sh +pmtiles show test.pmtiles --bucket=s3://BUCKET_NAME?endpoint=https://example.com®ion=auto +``` + +:::info +Some S3-compatible storage servers like Minio, Ceph and SeaweedFS may require [additional URL options](https://gocloud.dev/howto/blob/#s3-compatible) like `s3ForcePathStyle=true`. ::: +### Private buckets + +`pmtiles` uses [go-cloud's](https://gocloud.dev/howto/blob/) default authentication methods for each cloud provider. + +For example, the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables are used to sign requests to private S3-compatible buckets: + +```sh +export AWS_ACCESS_KEY_ID=MY_KEY +export AWS_SECRET_ACCESS_KEY=MY_SECRET +pmtiles show NAME.pmtiles --bucket=s3://R2_BUCKET_NAME\?endpoint=https://R2_ACCOUNT_ID.r2.cloudflarestorage.com\®ion=auto +``` + ## Commands ### show ```bash pmtiles show INPUT.pmtiles +pmtiles show INPUT.pmtiles --bucket=s3://BUCKET_NAME +pmtiles show INPUT.pmtiles --header-json +pmtiles show INPUT.pmtiles --metadata ``` Print an archive's header data and metadata. +* `--header-json`: print a JSON representation of part of the header to stdout. +* `--metadata`: print the JSON metadata to stdout. + ### tile ```bash pmtiles tile INPUT.pmtiles 0 0 0 ``` -Output a single tile to stdout. +Output a single tile's contents to stdout. ### verify @@ -50,25 +106,125 @@ Check that an archive is ordered correctly and has correct header information. ```bash pmtiles extract INPUT.pmtiles OUTPUT.pmtiles --bbox=MIN_LON,MIN_LAT,MAX_LON,MAX_LAT pmtiles extract INPUT.pmtiles OUTPUT.pmtiles --region=REGION.geojson +pmtiles extract https://example.com/INPUT.pmtiles OUTPUT.pmtiles --maxzoom=MAXZOOM +pmtiles extract INPUT.pmtiles OUTPUT.pmtiles --maxzoom=MAXZOOM --bucket=s3://BUCKET_NAME ``` -Create a smaller archive from a larger archive. +Create a smaller archive from a larger archive. The source archive may be local or remote. The source archive must be clustered. + +Options: + +* `--maxzoom`: Extract only a subset of zoom levels. Extracting a full sub-pyramid from 0 to `maxzoom` is always an efficient operation that makes minimal I/O or network requests to the source archive. +* `--minzoom`: Extract only a partial sub-pyramid. This may require many more requests than leaving the default `--minzoom=0`. Because this removes overview zoom levels, it should only be used in specific situations. +* `--region`: a [GeoJSON](https://geojson.org) Polygon, Multipolygon, Feature, or FeatureCollection. +* `--download-threads` Number of parallel requests to speed up downloads. +* `--overfetch` extra data to download to batch small requests: 0.05 is 5%. ### serve +The simplest way to consume PMTiles on the web is directly in the browser with [pmtiles.js along with a renderer-specific client](/pmtiles/maplibre). However, decoding PMTiles on the server and exposing a ZXY API works with more clients and can result in lower latency. A ZXY API is directly supported by web and native renderers such as [MapLibre](https://maplibre.org), without needing the PMTiles client library. Using `pmtiles serve` also allows serving a public API from a private storage bucket. + +:::info +When using `pmtiles serve`, requests for the raw file like `/test.pmtiles`, either whole or partial range requests, are not supported. A standard web server like Apache, Nginx or Caddy can serve those. +::: + +Serve a directory or bucket of tilesets (like TILESET.pmtiles) from local or cloud storage as a ZXY endpoint: + ```bash pmtiles serve . +# serves this directory at http://localhost:8080/TILESET/{z}/{x}/{y}.mvt +# the .pmtiles extension is added automatically +# TileJSON at http://localhost:8080/TILESET.json +pmtiles serve . --bucket=https://example.com +pmtiles serve / --bucket=s3://BUCKET_NAME +pmtiles serve PREFIX --bucket=s3://BUCKET_NAME ``` -Run a Z/X/Y server for a directory or bucket of archives. +For ZXY URLs, the extension must match the type of the tiles in the archive, for example `mvt`, `png`, `jpg`, `webp`, `avif`. + +Flags: + +* `--cors=ORIGIN1,ORIGIN2` set the valid origins for the `Access-Control-Allow-Origin` CORS header. `*` is a valid value but must be escaped in your shell. Appropriate for development use. +* `--cache-size=SIZE_MB` set the global size of the header and directory LRU cache, shared across all archives. Default is 64 MB. +* `--port=PORT` specify the HTTP port. Defaults to 8080. +* `--public-url`: Required for serving [TileJSON](https://github.com/mapbox/tilejson-spec/tree/master/3.0.0). Specify the full URL as it should appear to the browser client like `http://localhost:8080` or `https://example.com`. + +For production usage, it's recommended to run behind a CDN or reverse proxy like Caddy to handle SSL and CORS. See the guide on [Accelerating PMTiles](/deploy/). + ### convert +Convert an [MBTiles](https://github.com/mapbox/mbtiles-spec/tree/master/1.3) archive to PMTiles. + ```bash pmtiles convert INPUT.mbtiles OUTPUT.pmtiles ``` -Convert from MBTiles. +For the Docker image: + +```sh +docker run -v $(pwd):/data --rm protomaps/go-pmtiles convert /data/INPUT.mbtiles /data/OUTPUT.pmtiles +``` + +Options: + +* `--no-deduplication`: Do not attempt to de-duplicate tile contents. Use this to speed up `convert` if you know the input has only unique tiles. +* `--tmpdir`: specify the location of the temporary directory. + +### cluster + +Cluster an unclustered existing archive, optimizing the size and layout. Archives created by tippecanoe, planetiler, and the pmtiles CLI are already clustered. + +```bash +pmtiles cluster INPUT.pmtiles +``` + +Options: + +* `--no-deduplication`: Do not attempt to de-duplicate tile contents. Use this to speed up `cluster` if you know the input has only unique tiles. + +### upload + +Upload an archive to cloud storage. + +```bash +# requires environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY credentials +pmtiles upload INPUT.pmtiles REMOTE.pmtiles --bucket=s3://BUCKET_NAME +# upload to a s3-compatible endpoint +# some storage systems require path-style requests +pmtiles upload INPUT.pmtiles REMOTE.pmtiles --bucket=s3://BUCKET_NAME?region=auto&endpoint=https://example.com&use_path_style=true +``` + +You will need write permissions to the bucket, for example this AWS IAM policy: + +```json + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "s3:*", + "Resource": "arn:aws:s3:::my-bucket-name/*" + } + ] + } +``` + +### edit + +Change parts of the archive header, or replace the archive JSON metadata. + +```bash +pmtiles show NAME.pmtiles --header-json > header.json +pmtiles show NAME.pmtiles --metadata > metadata.json + +# make changes to header.json or metadata.json + +pmtiles edit NAME.pmtiles --header-json=header.json --metadata=metadata.json +``` + +* The `tile_type`, `tile_compresssion`, `minzoom`, `maxzoom`, `bounds` and `center` of the header can be edited. Other fields are not editable. Editing only the header will modify the file in-place. +* Writing the JSON metadata requires writing a new copy of the archive, which will then replace `NAME.pmtiles`. ### version diff --git a/pmtiles/cloud-storage.md b/pmtiles/cloud-storage.md index 61d6277..17afd97 100644 --- a/pmtiles/cloud-storage.md +++ b/pmtiles/cloud-storage.md @@ -21,6 +21,11 @@ PMTiles is designed to work on any S3-compatible cloud storage platform that sup rclone copyto my-filename my-configuration:my-bucket/my-folder/my-filename.pmtiles --progress --s3-chunk-size=256M ``` +RClone is also available via the [`rclone/rclone` Docker image.](https://hub.docker.com/r/rclone/rclone) + +1. `rclone config` and follow the on screen questions. In Docker, the config is located at `/etc/rclone`. +2. `rclone copyto :/ --progress --s3-no-check-bucket --s3-chunk-size=256M` to upload to the root of the bucket. + * The [aws command-line tool](https://aws.amazon.com/cli/) can be used for uploads, as well as setting CORS configuration on any S3-compatible platform. ::: info @@ -35,26 +40,24 @@ Storage services usually bill by number of GET requests and the total number of * R2 supports HTTP/2. -* R2 CORS must be configured through a command-line utility like the `aws` tool: +* R2 CORS can be configured through a command-line utility, like the `wrangler` tool, or from your Cloudflare R2 bucket's "Settings" tab's "CORS Policy" section: ```json title="cors_rules.json" { - "CORSRules": [ - { - "AllowedOrigins": ["https://example.com/"], - "AllowedHeaders": ["range"], - "AllowedMethods": ["GET","HEAD"], - "MaxAgeSeconds": 3000, - "ExposeHeaders": ["ETag"] - } - ] + "allowed": { + "origins": ["https://example.com/"], + "methods": ["GET","HEAD"], + "headers": ["range","if-match"], + }, + "exposeHeaders": ["etag"], + "maxAgeSeconds": 3000 } ``` -Example of using the `aws` command line tool to configure R2 CORS: +Example of using the `wrangler` command line tool to configure R2 CORS: ``` -aws s3api put-bucket-cors --bucket MY_BUCKET --cors-configuration file:///home/user/cors_rules.json --endpoint-url https://S3_COMPATIBLE_ENDPOINT +wrangler r2 bucket cors set MY_BUCKET --file file:///home/user/cors_rules.json ``` ### Amazon S3 @@ -88,10 +91,11 @@ S3 CORS Configuration: ```json title="s3_cors.json" [ { - "origin": ["https://example.com/"], - "method": ["GET","HEAD"], - "responseHeader": ["range","etag"], - "maxAgeSeconds": 300 + "AllowedOrigins": ["https://example.com/"], + "AllowedMethods": ["GET","HEAD"], + "AllowedHeaders": ["range","if-match"], + "ExposeHeaders": ["etag"], + "MaxAgeSeconds": 3000 } ] ``` @@ -104,21 +108,34 @@ S3 CORS Configuration: * See the [Cloud Storage CORS documentation](https://cloud.google.com/storage/docs/cross-origin) -* Install the [gsutil tool](https://cloud.google.com/storage/docs/gsutil_install) to set CORS headers +#### CORS: Google Cloud Shell + +``` +echo '[{"maxAgeSeconds": 300, "method": ["GET", "HEAD"], "origin": ["https://example.com/"], "responseHeader": ["range","etag","if-match"]}]' > cors.json + +gcloud storage buckets update gs://my-bucket-name --cors-file=cors.json +``` + +#### CORS: gcloud + +Install the [gcloud CLI](https://cloud.google.com/sdk/docs/install) to set a [CORS Configuration](https://cloud.google.com/storage/docs/cors-configurations): -```json title="google_cloud_cors.json" +```json title="cors.json" [ { "origin": ["https://example.com/"], "method": ["GET","HEAD"], - "responseHeader": ["range","etag"], + "responseHeader": ["range","etag","if-match"], "maxAgeSeconds": 300 } ] ``` ```bash -gsutil cors set google_cloud_cors.json gs://my-bucket-name +# view CORS settings +gcloud storage buckets describe gs://my-bucket-name --format="default(cors_config)" + +gcloud storage buckets update gs://my-bucket-name --cors-file=cors.json ``` ### Microsoft Azure @@ -128,7 +145,7 @@ gsutil cors set google_cloud_cors.json gs://my-bucket-name * Configuration through Web Portal * CORS Configuration - in left sidebar **Resource Sharing (CORS)** - * Set **Allowed Headers** to **Range** + * Set **Allowed Headers** to **range,if-match** * Set **Exposed Headers** to **range,accept-ranges,etag** ### DigitalOcean Spaces @@ -137,7 +154,19 @@ gsutil cors set google_cloud_cors.json gs://my-bucket-name * CORS is configured via Web UI. -* use S3Cmd config to expose `ETag` header +* use S3Cmd config to expose `etag` header + +### Bunny.net + +Bunny.net is a EU-headquartered content delivery network. PMTiles can be uploaded to a Bunny [Storage Zone](https://bunny.net/storage/) and accessed through an edge-cached [Pull Zone](https://support.bunny.net/hc/en-us/articles/207790269-How-to-create-your-first-Pull-Zone). + +Bunny does not offer an S3-compatible storage API. To upload a PMTiles archive to a Bunny storage zone: + +```sh +curl --request PUT --url https://SUBDOMAIN.storage.bunnycdn.com/BUCKET/example.pmtiles --header "AccessKey: ACCESS_KEY" --header "Content-Type: application/octet-stream" --header 'accept: application/json' -T EXAMPLE.pmtiles --progress-bar -o upload.txt +``` + +CORS can be enabled in the **Headers** section. Allowed referrers can be configured in the **Security > General** section. ### Backblaze B2 @@ -155,18 +184,103 @@ Sample CORS Configuration: "corsRuleName": "allowHeaders", "allowedOrigins": ["https://example.com/"], "allowedOperations":["b2_download_file_by_name"], - "allowedHeaders": ["range"], + "allowedHeaders": ["range","if-match"], "maxAgeSeconds": 300 } ] ``` +### Supabase Storage + +* [Supabase Storage](https://supabase.com/storage) is an S3-compatible storage API that supports HTTP Range Requests. +* [Private Buckets](https://supabase.com/docs/guides/storage/serving/downloads#private-buckets) integrate with the Supabase Auth system. +* [Public Buckets](https://supabase.com/docs/guides/storage/serving/downloads#public-buckets) allow all CORS origins (`*`) and benefit from a CDN edge cache. + +#### CORS + +Currently, limiting access to certain domains is only possible by proxying requests to Private Buckets through [Supabase Edge Functions](https://supabase.com/edge-functions), which has an additional billing model. + +This proxy Edge Function validates the request origin and attaches a header with your project's service role key. This allows you to serve files from private buckets while still benefitting from the built in [smart CDN](https://supabase.com/docs/guides/storage/cdn/smart-cdn). + +```ts +const ALLOWED_ORIGINS = ["http://localhost:3000/"]; +const corsHeaders = { + "Access-Control-Allow-Origin": ALLOWED_ORIGINS.join(","), + "Access-Control-Allow-Headers": + "authorization, x-client-info, apikey, content-type, range, if-match", + "Access-Control-Expose-Headers": "range, accept-ranges, etag", + "Access-Control-Max-Age": "300", +}; + +Deno.serve(async (req) => { + if (req.method === "OPTIONS") { + return new Response("ok", { headers: corsHeaders }); + } + + // Validate request origin. + const origin = req.headers.get("Origin"); + console.log(origin); + if (!origin || !ALLOWED_ORIGINS.includes(origin)) { + return new Response("Not Allowed", { status: 405 }); + } + + // Construct private bucket storage URL. + const reqUrl = new URL(req.url); + const url = `${ + Deno.env.get("SUPABASE_URL") + }/storage/v1/object/authenticated${reqUrl.pathname}`; + console.log(url); + + const { method, headers } = req; + // Add auth header to access file in private bucket. + const modHeaders = new Headers(headers); + modHeaders.append( + "authorization", + `Bearer ${Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!}`, + ); + return fetch(url, { method, headers: modHeaders }); +}); +``` + + +### Tigris Data + +* [Tigris Data](http://tigrisdata.com) is S3-compatible and offers buckets distributed to multiple locations around the world for low latency. +* Tigris data has [no egress fees](https://www.tigrisdata.com/docs/pricing/). + +#### CORS + +In the **Bucket > Settings** of your Tigris bucket, scroll to **CORS Configuration**. + +- For **Allowed Methods** and **Allowed Headers**, choose or input `*`. This is required for preflight requests. +- For **Expose Headers**, input `ETag`. + +### Source Cooperative + +[Source Cooperative](https://source.coop) is a publishing utility for open data operated by [Radiant Earth](https://radiant.earth/). + +To upload PMTiles to Source Cooperative, use the [pmtiles cli](/pmtiles/cli). + +On the **Manage** page of your source.coop repository, create an API key and find the **Access Key ID** and **Secret Access Key**. + +Then use `pmtiles upload` to copy the file to Source's S3-compatible endpoint: + +```sh +export AWS_ACCESS_KEY_ID=YOUR_KEY +export AWS_SECRET_ACCESS_KEY=YOUR_SECRET +pmtiles upload file.pmtiles path/in/bucket/key.pmtiles --bucket=s3://ORGANIZATION_NAME?endpoint=https://data.source.coop®ion=auto&use_path_style=true +``` + ## Other Platforms ### GitHub Pages GitHub pages supports repositories up to [1 GB](https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#usage-limits). If your PMTiles file fits, it's an easy way to host. +:::warning +PMTiles archives hosted on GitHub Pages currently do not load in Firefox. See [this GitHub issue](https://github.com/protomaps/PMTiles/issues/584) for the bug description and workaround. +::: + ### Scaleway [Scaleway Object Storage](https://www.scaleway.com/en/object-storage/) only supports HTTP/1.1. @@ -175,13 +289,33 @@ GitHub pages supports repositories up to [1 GB](https://docs.github.com/en/pages * [**Caddy**](https://caddyserver.com) is highly recommended for serving PMTiles because of its built-in HTTPS support. Use the `file_server` configuration to serve `.pmtiles` from a static directory. +CORS configuration: + +``` + Access-Control-Allow-Methods GET,HEAD + Access-Control-Expose-Headers ETag + Access-Control-Allow-Headers Range,If-Match + Access-Control-Allow-Origin http://example.com +``` + As an alternative, consider using the [`pmtiles_proxy` plugin for Caddy](/deploy/server). -* **Nginx** supports HTTP Range Requests. CORS headers should be set by configuration files. +* **Nginx** supports HTTP Range Requests. CORS headers should be set by configuration files. Your HTTP server will also need to support CORS Preflight requests (`OPTIONS` method) for full browser support. Example NGINX block: + +``` +if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Max-Age' 3600; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Access-Control-Allow-Origin' '*' always; + add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always; + add_header 'Content-Length' 0; + return 204; +} +``` ## Next steps * [Accelerate your maps and serve from private buckets with CDN integration](/deploy/). -* Learn how to customize your map's [Basemap Layers](/basemaps/layers). +* Learn how to style the [Basemap Layers](/basemaps/layers). diff --git a/pmtiles/create.md b/pmtiles/create.md index caf9696..c5a3483 100644 --- a/pmtiles/create.md +++ b/pmtiles/create.md @@ -17,6 +17,13 @@ ogr2ogr -t_srs EPSG:4326 cb_2018_us_zcta510_500k.json cb_2018_us_zcta510_500k.sh tippecanoe -zg --projection=EPSG:4326 -o cb_2018_us_zcta510_500k_nolimit.pmtiles -l zcta cb_2018_us_zcta510_500k.json ``` +To merge multiple pmtiles files into a single file use [`tile-join` tool](https://github.com/felt/tippecanoe?tab=readme-ov-file#tile-join), which is shipped with Tippecanoe + +```sh +# Merge all PMTiles files in current folder into single file +tile-join -o merged.pmtiles *.pmtiles +``` + ## MBTiles the [`pmtiles` command line tool](/pmtiles/cli) converts MBTiles to PMTiles with this command: @@ -25,26 +32,53 @@ the [`pmtiles` command line tool](/pmtiles/cli) converts MBTiles to PMTiles with ## GeoTIFF -Using a file from [OSGeo's GeoTIFF samples](https://download.osgeo.org/geotiff/samples/) and the [rio-mbtiles](https://github.com/mapbox/rio-mbtiles) Python tool: +The [rio-pmtiles](https://pypi.org/project/rio-pmtiles/) package is a plugin for the [Rasterio](https://rasterio.readthedocs.io/en/stable/) python library and CLI. + +Using a file from [OSGeo's GeoTIFF samples](https://download.osgeo.org/geotiff/samples/): ```sh # convert single-band to 3-band RGB GeoTIFF gdal_translate -expand rgb input.tif input_rgb.tif -# in this example create 512x512 PNG tiles from zooms 0 to 16. -rio mbtiles input_rgb.tif output.mbtiles --format PNG --zoom-levels 0..16 --tile-size 512 --resampling bilinear +pip install rio-pmtiles -pmtiles convert output.mbtiles output.pmtiles +rio pmtiles input_rgb.tif output.pmtiles --format PNG --resampling bilinear ``` +Options: + +* `--format`: One of `PNG` (lossless), `JPEG`, `WEBP`. `JPEG` is fastest to generate. Default `WEBP`. +* `--tile-size`: the dimensions in pixels. 512 is recommended for displaying in MapLibre GL. default `512`. +* `--resampling`: Choose `nearest` for discrete data. Default `bilinear`. +* `--silent`: Don't show a progress bar. +* `--zoom-levels`: Specify a range `10..12` to only generate those zoom levels. By default, generates all levels between 0 and the level to capture the full detail of the input. +* `--help`: Show other advanced options and GDAL flags. + + ## GDAL -::: warning -This section is under construction. -::: +GDAL has native support for PMTiles starting with version 3.8.0 (2023-11-13), see [gdal.org/drivers/vector/pmtiles](https://gdal.org/drivers/vector/pmtiles.html) for details. + +**Using ogr2ogr to create vector PMTiles is recommended only for smaller datasets: the [tippecanoe](#tippecanoe) tool creates much more efficient overview tiles.** + +GDAL's [`ogr2ogr`](https://gdal.org/programs/ogr2ogr.html#ogr2ogr) tool supports a wide range of formats as input for creating PMTiles. Below are examples of generating PMTiles from a Shapefile or multiple PostgreSQL/PostGIS tables. + +```sh +# Convert shapefile to pmtiles +ogr2ogr -dsco MINZOOM=10 -dsco MAXZOOM=15 -f "PMTiles" filename.pmtiles my_shapes.shp + +# Merge all PostgreSQL/PostGIS tables in a schema into a single PMTiles file. +ogr2ogr -dsco MINZOOM=0 -dsco MAXZOOM=15 -f "PMTiles" filename.pmtiles "PG:host=my_host port=my_port dbname=my_database user=my_user password=my_password schemas=my_schema" +``` + +* `MAXZOOM=15` is sufficient for street-level mapping. Choosing less detail with a lower `MAXZOOM` will reduce the size of the final file. + +## protomaps/basemaps + +The [basemaps](https://github.com/protomaps/basemaps) repository on GitHub contains a java [Planetiler](https://github.com/onthegomap/planetiler) profile for generating planet-scale PMTiles from OpenStreetMap. The layers in this tileset are documented at [Basemap Layers](/basemaps/layers) and daily builds can be downloaded for free from [maps.protomaps.com/builds](https://maps.protomaps.com/builds). + +Run the basemaps program on your own computer to modify the layers or generate only one specific area. -## Other +## Tilemaker -::: warning -This section is under construction. -::: +[Tilemaker](https://github.com/systemed/tilemaker) is a program for creating basemap tilesets from OpenStreetMap, though not ones that match the layers in the Protomaps [Basemap Layers](/basemaps/layers). The PMTiles archives that Tilemaker produces are currently not clustered, which may result in large, slower fetches when decoding in a web browser. For production use you should optimize the archive with [pmtiles cluster](/pmtiles/cli#cluster). diff --git a/pmtiles/index.md b/pmtiles/index.md index c8f00fc..fdef70b 100644 --- a/pmtiles/index.md +++ b/pmtiles/index.md @@ -15,15 +15,31 @@ PMTiles is a single-file archive format for pyramids of tiled data. A PMTiles ar * The arrangement of tiles and directories is designed to minimize the amount of overhead requests when panning and zooming. +* PMTiles is a **read-only** format. It is not possible to update an archive in-place without re-writing the entire file, similar to CSV, JSON and Parquet. If you need transactional updates, use a database like SQLite or [PostgreSQL](http://postgis.net) + [ST_asMVT](https://postgis.net/docs/ST_AsMVT.html). + The current specification version of PMTiles is version 3, which you can [read on GitHub.](https://github.com/protomaps/PMTiles/blob/master/spec/v3/spec.md) +## Comparisons + +### Individual files + +An alternative to PMTiles is uploading each tile separately in a directory tree like `/Z/X/Y.mvt`. This works great for small tilesets, but uploading full global pyramid, such as 300 million tiles, could cost 1,500 USD in request fees and take days. PMTiles is a single file to upload and de-duplicates tiles internally, reducing size by 70%+ or more for global vector basemaps. + +### MBTiles + +[MBTiles](https://github.com/mapbox/mbtiles-spec) is a container format for tiled data, just like PMTiles, but based on SQLite. MBTiles are designed to be accessed on disk from a running server process, while PMTiles is designed to be read remotely over HTTP, with at most two cacheable intermediate requests. + +### Cloud Optimized GeoTIFF + +A [Cloud Optimized GeoTIFF (COG)](https://www.cogeo.org) is a raster TIFF file with an internal organization that enables remote reads from cloud storage. PMTiles is similar to COG, but stores arbitrary tiled data, such as vector MVT tiles. However, COG is backwards compatible with most GIS software that deals with GeoTIFF. + ## Reading PMTiles ### PMTiles Viewer The Viewer is a browser-based tool for visualizing PMTiles on a map, inspecting metadata, and debugging individual tiles. -You can access the Viewer at [protomaps.github.io/PMTiles/](https://protomaps.github.io/PMTiles/). +You can access the Viewer at [pmtiles.io](https://pmtiles.io/). ### Serving files locally @@ -44,13 +60,19 @@ See the [pmtiles cli](/pmtiles/cli). ### JavaScript -PMTiles is designed for being read directly in web browsers in conjunction with a JavaScript map library. +PMTiles is designed for being viewed directly in web browsers in conjunction with a JavaScript map rendering library, including: + +* [MapLibre GL JS](/pmtiles/maplibre) - the recommended library for building smooth experiences and custom styling. +* [Leaflet](/pmtiles/leaflet) - a lightweight map display library with many plugins. +* [OpenLayers](/pmtiles/openlayers) - has the most GIS-related features. + +Each of the client integrations uses the [JavaScript pmtiles library](https://github.com/protomaps/PMTiles/tree/main/js). -See the docs on viewing PMTiles in [Leaflet](/pmtiles/leaflet), [MapLibre GL JS](/pmtiles/maplibre) and [OpenLayers](/pmtiles/openlayers). +[JavaScript Library API documentation](https://pmtiles.io/typedoc/) ### Python -`pmtiles` is a python package for reading and writing PMTiles. [GitHub](https://github.com/protomaps/PMTiles/tree/master/python) and via the [Python Package Index](https://pypi.org/project/pmtiles/). +`pmtiles` is a python package for reading and writing PMTiles. It is available via [GitHub](https://github.com/protomaps/PMTiles/tree/main/python) and the [Python Package Index](https://pypi.org/project/pmtiles/). ::: warning The Python `pmtiles` package should be considered beta status. @@ -61,3 +83,4 @@ The Python `pmtiles` package should be considered beta status. These libraries are maintained by other individuals and organizations. * Dart: [pub.dev/packages/pmtiles](https://pub.dev/packages/pmtiles) +* Rust: [stadiamaps/pmtiles-rs](https://github.com/stadiamaps/pmtiles-rs) diff --git a/pmtiles/leaflet.md b/pmtiles/leaflet.md index f35eb59..ddeec89 100644 --- a/pmtiles/leaflet.md +++ b/pmtiles/leaflet.md @@ -17,32 +17,20 @@ The base distribution of Leaflet only supports raster images for tiled data sour Add a raster PMTiles archive using the `pmtiles` library: ```js -import * as pmtiles from 'pmtiles'; -const p = new pmtiles.PMTiles('https://example.com/data.pmtiles'); -pmtiles.leafletRasterLayer(p).addTo(map) +import { PMTiles, leafletRasterLayer } from 'pmtiles'; +const p = new PMTiles('https://example.com/data.pmtiles'); +leafletRasterLayer(p).addTo(map) ```` -## Vector: protomaps-leaflet +## Vector PMTiles Protomaps publishes a lightweight Leaflet plugin, [protomaps-leaflet](https://github.com/protomaps/protomaps-leaflet), that implements **vector drawing and text labels** built on the Canvas API and Web Fonts. -## Vector Basemaps +Note that the protomaps-leaflet library is **designed for non-interactive layers**, because it renders vector tiles to Canvas (image) elements. -The simplest way to include a map in your application via script includes tag: +For basemap display as a substitute for server-rendered tiles, see [Basemaps for Leaflet](/basemaps/leaflet). -```js -// check for the latest version on github... - - -``` - -By default, this will assume the set of basemap layers described at [Basemap Layers](/basemaps/layers), so you should see a map that looks like this: - -![detroit](https://protomaps.github.io/protomaps-leaflet/benchmark/example_1.png) +For fully interactive vector overlay tiles you should use [MapLibre GL JS](/pmtiles/maplibre). ## Custom Vector Data @@ -66,8 +54,8 @@ let LABEL_RULES = []; // ignore for now protomapsL.leafletLayer({ url:URL, - paint_rules:PAINT_RULES, - label_rules:LABEL_RULES + paintRules:PAINT_RULES, + labelRules:LABEL_RULES }).addTo(map) ``` diff --git a/pmtiles/maplibre.md b/pmtiles/maplibre.md index 1afd736..ad36201 100644 --- a/pmtiles/maplibre.md +++ b/pmtiles/maplibre.md @@ -5,22 +5,26 @@ outline: deep # PMTiles for MapLibre GL +PMTiles is designed to be read directly in the browser by the MapLibre GL renderer, for either thematic overlay tilesets or basemap tilesets. + +For a guide on integrating the Protomaps basemap tileset into MapLibre GL, see [Basemaps for MapLibre](/basemaps/maplibre). + ## Installation For reading PMTiles directly from cloud storage, you'll need the `pmtiles` JavaScript library. -The JavaScript library includes a plugin for MapLibre GL that uses its [`addProtocol` feature.](https://maplibre.org/maplibre-gl-js-docs/api/properties/#addprotocol) +The JavaScript library includes a plugin for MapLibre GL that uses its [`addProtocol` feature.](https://maplibre.org/maplibre-gl-js/docs/API/functions/addProtocol/) ```bash npm install pmtiles ``` ```js -import * as pmtiles from "pmtiles"; +import { Protocol } from "pmtiles"; ``` ```js -let protocol = new pmtiles.Protocol(); +let protocol = new Protocol(); maplibregl.addProtocol("pmtiles",protocol.tile); ``` @@ -73,7 +77,7 @@ For raster tiles you'll just need to change the `type` of your source to `raster } ``` -Protomaps also distributes terrain tilesets in the [Terrarium RGB encoding](https://github.com/tilezen/joerd/blob/master/docs/formats.md). These have a special source type in MapLibre GL: +Protomaps also [distributes terrain tilesets](/basemaps/downloads#terrain) in the [Terrarium RGB encoding](https://github.com/tilezen/joerd/blob/master/docs/formats.md). These have a special source type in MapLibre GL: ```json{5} @@ -87,3 +91,7 @@ Protomaps also distributes terrain tilesets in the [Terrarium RGB encoding](http } } ``` + +## Next Steps + +* Integrating [Basemap Styles](/basemaps/maplibre) into MapLibre diff --git a/pmtiles/openlayers.md b/pmtiles/openlayers.md index 078b6c1..327a0c7 100644 --- a/pmtiles/openlayers.md +++ b/pmtiles/openlayers.md @@ -9,9 +9,9 @@ See [the openlayers/ directory](https://github.com/protomaps/PMTiles/tree/main/o ## Quick Example -Example of vector tiles (New Zealand buildings): [Live demo](https://protomaps.github.io/PMTiles/examples/openlayers/vector.html) +Example of vector tiles (New Zealand buildings): [Live demo](https://pmtiles.io/examples/openlayers/vector.html) -Example of raster tiles (RGB Terrain): [Live demo](https://protomaps.github.io/PMTiles/examples/openlayers/raster.html) +Example of raster tiles (RGB Terrain): [Live demo](https://pmtiles.io/examples/openlayers/raster.html) ## Using with a Bundler diff --git a/public/favicon.png b/public/favicon.png new file mode 100644 index 0000000..be41641 Binary files /dev/null and b/public/favicon.png differ diff --git a/public/logo.svg b/public/logo.svg index 21e3349..4945092 100644 --- a/public/logo.svg +++ b/public/logo.svg @@ -1,6 +1,35 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file