diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 355a3d0..0000000 --- a/.eslintrc +++ /dev/null @@ -1,215 +0,0 @@ -{ - "env": { - "es6": true, - "node": true, - "mocha": true - }, - "extends": [ - "eslint:recommended" - ], - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "module" - }, - "globals": { - "XMLSerializer": true, - "Blob": true, - "Image": true, - "Promise": true, - "XMLHttpRequest": true, - "FileReader": true, - "HTMLElement": true, - "CanvasRenderingContext2D": true, - "Worker": true, - "URL": true - }, - "plugins": [ - "promise", - "import-order", - "jsdoc" - ], - "rules": { - "indent": 0, - // "prefer-const": "error", - // "no-var": "error", - "prefer-arrow-callback": "error", - "arrow-parens": 0, - "strict": [ - // use strict mode - "error", - "global" - ], - "no-unused-vars": [ - "error", - { - "argsIgnorePattern": "^_" - } - ], - "no-constant-condition": [ - "error" - ], - "no-multi-spaces": 0, - "semi": [ - // semicolons are required - "error", - "always" - ], - "max-len": [ - // max line length is 120 chars (except for comments) - "error", - 120, - { - "ignoreComments": true - } - ], - "eol-last": [ - // \n is required at the end of the file - "error", - "always" - ], - "camelcase": [ - // enforce camelcase style for variable names and property names - "error", - { - "properties": "always" - } - ], - "dot-notation": [ - // always use the dot notation to access properties, except if property contains '_' - "error", - { - "allowPattern": "^.*_.*$" - } - ], - "quotes": [ - // use single quotes (or backticks if there is a substitution) - "error", - "single" - ], - "comma-dangle": [ - // no trailing commas in object or array literals - "error", - "never" - ], - "no-multi-str": [ - // no multi line strings using \ - "error" - ], - "no-multiple-empty-lines": [ - "error" - ], - "no-trailing-spaces": [ - "error" - ], - "no-mixed-spaces-and-tabs": [ - "error" - ], - "curly": 0, - "brace-style": 0, - "keyword-spacing": [ - // in `} else {` both spaces are required (in general, around keywords) - "error", - { - "before": true, - "after": true, - "overrides": { - "catch": { - "before": true, - "after": false - } - } - } - ], - "space-before-blocks": [ - // in `if (foo) {` the second space is required - "error", - "always" - ], - "arrow-spacing": [ - // in `(foo) => {` both spaces are required - "error", - { - "before": true, - "after": true - } - ], - "operator-linebreak": [ - // linebreak goes after the operator except for '?' and ':' - "error", - "after", - { - "overrides": { - "?": "before", - ":": "before" - } - } - ], - "space-unary-ops": [ - // space is required for new, delete, etc. but not for +, -, ++, --, etc. - "error", - { - "words": true, - "nonwords": false, - "overrides": { - "typeof": false - // also no space for typeof(...) - } - } - ], - "space-infix-ops": [ - // space is required around infix operators, e.g: 'a + b' - "error" - ], - "comma-spacing": [ - // space is required after a comma - "error", - { - "after": true - } - ], - "array-bracket-spacing": 0, - "space-in-parens": [ - // '( x + y )' is not allowed, use '(x + y)' - "error", - "never" - ], - "key-spacing": 0, - "yoda": [ - // disallow yoda conditions, e.g. `(true === foo)` - "error", - "never" - ], - "no-with": [ - // the with statements is not allowed - "error" - ], - "linebreak-style": [ - // use unix linebreak '\n' - "error", - "unix" - ], - "wrap-iife": [ - // require IIFE to be wrapped in parenthesis - "error" - ], - "func-call-spacing": [ - // no space between the function name and the opening parenthesis on invocation - "error", - "never" - ], - "space-before-function-paren": 0, - "no-cond-assign": [ - // no assignment operators in if, for and while except if enclosed in parentheses - "error", - "except-parens" - ], - "no-inner-declarations": [ - "error" - ], - "no-console": 2, - // `console.log(...)` is allowed - "import-order/import-order": 0, - // import order is not enfored - "no-case-declarations": 0 - } -} diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..214c29d --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +registry=https://registry.npmjs.org/ diff --git a/bench.js b/bench.js deleted file mode 100644 index ca906ae..0000000 --- a/bench.js +++ /dev/null @@ -1,58 +0,0 @@ -import load from 'load-json-file'; -import Benchmark from 'benchmark'; -import jstsUnion from '@turf/union'; -import martinez from './dist/martinez.umd'; - - -/** - * Benmark Results - * - * Hole_Hole x 13,345 ops/sec ±2.13% (91 runs sampled) - * Hole_Hole - JSTS x 1,724 ops/sec ±4.80% (87 runs sampled) - * Asia x 6.32 ops/sec ±3.16% (20 runs sampled) - * Asia - JSTS x 6.62 ops/sec ±2.74% (21 runs sampled) - */ - -const options = { - onStart (event) { console.log(this.name); }, - onError (event) { console.log(event.target.error); }, - onCycle (event) { console.log(String(event.target)); }, - onComplete() { - console.log('- Fastest is ' + this.filter('fastest').map('name') + '\n'); - } -}; - -const hole_hole = load.sync('./test/fixtures/hole_hole.geojson'); -new Benchmark.Suite('Hole_Hole', options) - .add('Martinez', () => { - martinez.union( - hole_hole.features[0].geometry.coordinates, - hole_hole.features[1].geometry.coordinates); - }) - .add('JSTS', () => { - jstsUnion(hole_hole.features[0], hole_hole.features[1]); - }) - .run(); - -const asia = load.sync('./test/fixtures/asia.geojson'); -const unionPoly = load.sync('./test/fixtures/asia_unionPoly.geojson'); -new Benchmark.Suite('Asia union', options) - .add('Martinez', () => { - martinez.union( - asia.features[0].geometry.coordinates, - unionPoly.geometry.coordinates); - }) - .add('JSTS', () => jstsUnion(asia.features[0], unionPoly)) - .run(); - -const states = load.sync('./test/fixtures/states_source.geojson'); -new Benchmark.Suite('States clip', options) - .add('Martinez', () => { - martinez.union( - states.features[0].geometry.coordinates, - states.features[1].geometry.coordinates); - }) - .add('JSTS', () => { - jstsUnion(states.features[0], states.features[1]); - }) - .run(); diff --git a/bench/martinez.bench.ts b/bench/martinez.bench.ts new file mode 100644 index 0000000..2897ead --- /dev/null +++ b/bench/martinez.bench.ts @@ -0,0 +1,63 @@ +import { describe, bench } from 'vitest'; +import { readFileSync } from 'fs'; +import { join } from 'path'; +import jstsUnion from '@turf/union'; +import * as martinez from '../index'; + +/** + * Benchmark Results + * + * Previous results with Benchmark.js: + * Hole_Hole x 13,345 ops/sec ±2.13% (91 runs sampled) + * Hole_Hole - JSTS x 1,724 ops/sec ±4.80% (87 runs sampled) + * Asia x 6.32 ops/sec ±3.16% (20 runs sampled) + * Asia - JSTS x 6.62 ops/sec ±2.74% (21 runs sampled) + */ + +// Helper to load JSON files +const loadJSON = (filePath: string) => JSON.parse(readFileSync(filePath, 'utf-8')); + +// Load test fixtures +const hole_hole = loadJSON(join(__dirname, '../test/fixtures/hole_hole.geojson')); +const asia = loadJSON(join(__dirname, '../test/fixtures/asia.geojson')); +const unionPoly = loadJSON(join(__dirname, '../test/fixtures/asia_unionPoly.geojson')); +const states = loadJSON(join(__dirname, '../test/fixtures/states_source.geojson')); + +describe('Hole_Hole union', () => { + bench('Martinez', () => { + martinez.union( + hole_hole.features[0].geometry.coordinates, + hole_hole.features[1].geometry.coordinates + ); + }); + + bench('JSTS', () => { + jstsUnion(hole_hole.features[0], hole_hole.features[1]); + }); +}); + +describe('Asia union', () => { + bench('Martinez', () => { + martinez.union( + asia.features[0].geometry.coordinates, + unionPoly.geometry.coordinates + ); + }); + + bench('JSTS', () => { + jstsUnion(asia.features[0], unionPoly); + }); +}); + +describe('States clip', () => { + bench('Martinez', () => { + martinez.union( + states.features[0].geometry.coordinates, + states.features[1].geometry.coordinates + ); + }); + + bench('JSTS', () => { + jstsUnion(states.features[0], states.features[1]); + }); +}); diff --git a/demo/booleanopcontrol.ts b/demo/booleanopcontrol.ts new file mode 100644 index 0000000..766d181 --- /dev/null +++ b/demo/booleanopcontrol.ts @@ -0,0 +1,99 @@ +import L from "leaflet"; + +declare module "leaflet" { + interface BooleanControlOptions extends ControlOptions { + callback?: (op: number) => void; + clear?: () => void; + } + + namespace Control { + class BooleanControl extends Control { + constructor(options?: BooleanControlOptions); + options: BooleanControlOptions; + } + } +} + +(L as any).BooleanControl = L.Control.extend({ + options: { + position: "topright", + }, + + onAdd: function (this: any, map: L.Map) { + const container = (this._container = L.DomUtil.create( + "div", + "leaflet-bar" + )); + this._container.style.background = "#ffffff"; + this._container.style.padding = "10px"; + container.innerHTML = [ + "
", + '", + '', + '', + "
", + ].join(""); + const form = container.querySelector("form")!; + L.DomEvent.on( + form, + "submit", + function (this: any, evt: Event) { + L.DomEvent.stop(evt); + const radios = Array.prototype.slice.call( + form.querySelectorAll("input[type=radio]") + ) as HTMLInputElement[]; + for (let i = 0, len = radios.length; i < len; i++) { + if (radios[i].checked) { + this.options.callback(parseInt(radios[i].value)); + break; + } + } + }, + this + ).on( + (form as any)["clear"], + "click", + function (this: any, evt: Event) { + L.DomEvent.stop(evt); + this.options.clear(); + }, + this + ); + + L.DomEvent.disableClickPropagation( + this._container + ).disableScrollPropagation(this._container); + return this._container; + }, +}); diff --git a/demo/coordinates.ts b/demo/coordinates.ts new file mode 100644 index 0000000..1d7b657 --- /dev/null +++ b/demo/coordinates.ts @@ -0,0 +1,41 @@ +import L from "leaflet"; + +declare module "leaflet" { + interface ControlOptions { + position?: "topleft" | "topright" | "bottomleft" | "bottomright"; + } + + namespace Control { + class Coordinates extends Control { + constructor(options?: ControlOptions); + } + } + + function coordinates(options?: ControlOptions): Control.Coordinates; +} + +L.Control.Coordinates = L.Control.extend({ + options: { + position: "bottomright", + }, + + onAdd: function (this: any, map: L.Map) { + this._container = L.DomUtil.create("div", "leaflet-bar"); + this._container.style.background = "#ffffff"; + map.on("mousemove", this._onMouseMove, this); + return this._container; + }, + + _onMouseMove: function (this: any, e: L.LeafletMouseEvent) { + this._container.innerHTML = + '' + + e.latlng.lng.toFixed(3) + + ", " + + e.latlng.lat.toFixed(3) + + ""; + }, +}); + +(L as any).Coordinates = function (options?: L.ControlOptions) { + return new (L.Control as any).Coordinates(options); +}; diff --git a/demo/css/styles.css b/demo/css/styles.css deleted file mode 100644 index 8f01df1..0000000 --- a/demo/css/styles.css +++ /dev/null @@ -1,19 +0,0 @@ -html, body, -#image-map { - width: 100%; - height: 100%; - margin: 0; - padding: 0; -} - -#diff-map, -#union-map, -#intersection-map { - display: none; - width: 400px; - height: 400px; - margin-right: 10px; - float: left; -} - -@import url("../../node_modules/leaflet-draw/dist/leaflet.draw.css") screen; diff --git a/demo/fixtures b/demo/fixtures new file mode 120000 index 0000000..6201ead --- /dev/null +++ b/demo/fixtures @@ -0,0 +1 @@ +../test/fixtures \ No newline at end of file diff --git a/demo/index.html b/demo/index.html index 310208b..169f056 100644 --- a/demo/index.html +++ b/demo/index.html @@ -1,23 +1,16 @@ - + - - + + Martinez Clipping - - - - - - - - - - - - + + - + diff --git a/demo/index.ts b/demo/index.ts new file mode 100644 index 0000000..7a08330 --- /dev/null +++ b/demo/index.ts @@ -0,0 +1,253 @@ +import "./coordinates"; +import "./polygoncontrol"; +import "./booleanopcontrol"; +import * as martinez from "../index"; +import L from "leaflet"; +import "leaflet-editable"; +import "leaflet/dist/leaflet.css"; +import * as jsts from "jsts"; + +declare global { + interface Window { + map: L.Map; + drawnItems: L.GeoJSON; + results: L.GeoJSON; + jsts: any; + } +} + +const mode = window.location.hash.substring(1); +const path = "./fixtures/"; +let file: string; + +switch (mode) { + case "geo": + file = "asia.geojson"; + break; + case "states": + file = "states_source.geojson"; + break; + case "trapezoid": + file = "trapezoid-box.geojson"; + break; + case "canada": + file = "canada.geojson"; + break; + case "horseshoe": + file = "horseshoe.geojson"; + break; + case "hourglasses": + file = "hourglasses.geojson"; + break; + case "edge_overlap": + file = "polygon_trapezoid_edge_overlap.geojson"; + break; + case "touching_boxes": + file = "touching_boxes.geojson"; + break; + case "triangles": + file = "two_pointed_triangles.geojson"; + break; + case "holecut": + file = "hole_cut.geojson"; + break; + case "overlapping_segments": + file = "overlapping_segments.geojson"; + break; + case "overlap_loop": + file = "overlap_loop.geojson"; + break; + case "overlap_y": + file = "overlap_y.geojson"; + break; + case "overlap_two": + file = "overlap_two.geojson"; + break; + case "disjoint_boxes": + file = "disjoint_boxes.geojson"; + break; + case "polygons_edge_overlap": + file = "polygons_edge_overlap.geojson"; + break; + case "vertical_boxes": + file = "vertical_boxes.geojson"; + break; + case "collapsed": + file = "collapsed.geojson"; + break; + case "fatal1": + file = "fatal1.geojson"; + break; + case "fatal2": + file = "fatal2.geojson"; + break; + case "fatal3": + file = "fatal3.geojson"; + break; + case "fatal4": + file = "fatal4.geojson"; + break; + case "rectangles": + file = "rectangles.geojson"; + break; + default: + file = "hole_hole.geojson"; + break; +} + +console.log(mode); + +enum OPERATIONS { + INTERSECTION = 0, + UNION = 1, + DIFFERENCE = 2, + XOR = 3, +} + +const div = document.createElement("div"); +div.id = "image-map"; +div.style.width = div.style.height = "100%"; +document.body.appendChild(div); + +// create the slippy map +const map = (window.map = L.map("image-map", { + minZoom: 1, + maxZoom: 20, + center: [0, 0], + zoom: 2, + crs: + mode === "geo" + ? L.CRS.EPSG4326 + : L.extend({}, L.CRS.Simple, { + transformation: new L.Transformation(1 / 8, 0, -1 / 8, 0), + }), + editable: true, +} as any)); + +map.addControl( + new (L as any).NewPolygonControl({ + callback: (map as any).editTools.startPolygon, + }) +); +map.addControl(new (L.Control as any).Coordinates()); +map.addControl( + new (L as any).BooleanControl({ + callback: run, + clear: clear, + }) +); + +const drawnItems = (window.drawnItems = L.geoJSON().addTo(map)); +let rawData: any = null; + +function loadData(path: string) { + console.log(path); + fetch(path) + .then((r) => r.json()) + .then((json) => { + drawnItems.addData(json); + rawData = json; + map.fitBounds(drawnItems.getBounds().pad(0.05), { animate: false }); + }); +} + +function clear() { + drawnItems.clearLayers(); + results.clearLayers(); + rawData = null; +} + +const reader = new jsts.io.GeoJSONReader(); +const writer = new jsts.io.GeoJSONWriter(); + +function getClippingPoly(layers: L.Layer[]): any { + if (rawData !== null && rawData.features.length > 1) + return rawData.features[1]; + return (layers[1] as any).toGeoJSON(); +} + +function run(op: number) { + const layers = drawnItems.getLayers(); + if (layers.length < 2) return; + let subject = + rawData !== null ? rawData.features[0] : (layers[0] as any).toGeoJSON(); + let clipping = getClippingPoly(layers); + + let operation: (a: any, b: any) => any; + if (op === OPERATIONS.INTERSECTION) { + operation = martinez.intersection; + } else if (op === OPERATIONS.UNION) { + operation = martinez.union; + } else if (op === OPERATIONS.DIFFERENCE) { + operation = martinez.diff; + } else if (op === 5) { + // B - A + operation = martinez.diff; + const temp = subject; + subject = clipping; + clipping = temp; + } else { + operation = martinez.xor; + } + + console.time("martinez"); + const result = operation( + subject.geometry.coordinates, + clipping.geometry.coordinates + ); + console.timeEnd("martinez"); + + console.log("result", result); + results.clearLayers(); + + if (result !== null) { + results.addData({ + type: "Feature", + geometry: { + type: "MultiPolygon", + coordinates: result, + }, + }); + + setTimeout(function () { + console.time("jsts"); + const s = reader.read(subject); + const c = reader.read(clipping); + let res; + if (op === OPERATIONS.INTERSECTION) { + res = s.geometry.intersection(c.geometry); + } else if (op === OPERATIONS.UNION) { + res = s.geometry.union(c.geometry); + } else if (op === OPERATIONS.DIFFERENCE) { + res = s.geometry.difference(c.geometry); + } else { + res = s.geometry.symDifference(c.geometry); + } + res = writer.write(res); + console.timeEnd("jsts"); + }, 500); + } +} + +map.on("editable:created", function (evt: any) { + drawnItems.addLayer(evt.layer); + evt.layer.on("click", function (this: any, e: any) { + if ( + (e.originalEvent.ctrlKey || e.originalEvent.metaKey) && + this.editEnabled() + ) { + this.editor.newHole(e.latlng); + } + }); +}); + +const results = (window.results = L.geoJSON(null, { + style: function (feature) { + return { + color: "red", + weight: 1, + }; + }, +}).addTo(map)); + +loadData(path + file); diff --git a/demo/js/booleanopcontrol.js b/demo/js/booleanopcontrol.js deleted file mode 100644 index 3b74481..0000000 --- a/demo/js/booleanopcontrol.js +++ /dev/null @@ -1,47 +0,0 @@ -import L from 'leaflet'; - -L.BooleanControl = L.Control.extend({ - options: { - position: 'topright' - }, - - onAdd: function(map) { - var container = this._container = L.DomUtil.create('div', 'leaflet-bar'); - this._container.style.background = '#ffffff'; - this._container.style.padding = '10px'; - container.innerHTML = [ - '
', - '', - '', '', - '
'].join(''); - var form = container.querySelector('form'); - L.DomEvent - .on(form, 'submit', function (evt) { - L.DomEvent.stop(evt); - var radios = Array.prototype.slice.call( - form.querySelectorAll('input[type=radio]')); - for (var i = 0, len = radios.length; i < len; i++) { - if (radios[i].checked) { - this.options.callback(parseInt(radios[i].value)); - break; - } - } - }, this) - .on(form['clear'], 'click', function(evt) { - L.DomEvent.stop(evt); - this.options.clear(); - }, this); - - L.DomEvent - .disableClickPropagation(this._container) - .disableScrollPropagation(this._container); - return this._container; - } - -}); diff --git a/demo/js/bundle.js b/demo/js/bundle.js deleted file mode 100644 index df83419..0000000 --- a/demo/js/bundle.js +++ /dev/null @@ -1,2390 +0,0 @@ -(function (L$1) { - 'use strict'; - - L$1 = L$1 && Object.prototype.hasOwnProperty.call(L$1, 'default') ? L$1['default'] : L$1; - - L$1.Coordinates = L$1.Control.extend({ - options: { - position: 'bottomright' - }, - - onAdd: function(map) { - this._container = L$1.DomUtil.create('div', 'leaflet-bar'); - this._container.style.background = '#ffffff'; - map.on('mousemove', this._onMouseMove, this); - return this._container; - }, - - _onMouseMove: function(e) { - this._container.innerHTML = '' + - e.latlng.lng.toFixed(3) + ', ' + e.latlng.lat.toFixed(3) + ''; - } - - }); - - L$1.EditControl = L$1.Control.extend({ - - options: { - position: 'topleft', - callback: null, - kind: '', - html: '' - }, - - onAdd: function (map) { - var container = L$1.DomUtil.create('div', 'leaflet-control leaflet-bar'), - link = L$1.DomUtil.create('a', '', container); - - link.href = '#'; - link.title = 'Create a new ' + this.options.kind; - link.innerHTML = this.options.html; - L$1.DomEvent.on(link, 'click', L$1.DomEvent.stop) - .on(link, 'click', function () { - window.LAYER = this.options.callback.call(map.editTools); - }, this); - - return container; - } - - }); - - L$1.NewPolygonControl = L$1.EditControl.extend({ - options: { - position: 'topleft', - kind: 'polygon', - html: '▰' - } - }); - - L$1.BooleanControl = L$1.Control.extend({ - options: { - position: 'topright' - }, - - onAdd: function(map) { - var container = this._container = L$1.DomUtil.create('div', 'leaflet-bar'); - this._container.style.background = '#ffffff'; - this._container.style.padding = '10px'; - container.innerHTML = [ - '
', - '', - '', '', - '
'].join(''); - var form = container.querySelector('form'); - L$1.DomEvent - .on(form, 'submit', function (evt) { - L$1.DomEvent.stop(evt); - var radios = Array.prototype.slice.call( - form.querySelectorAll('input[type=radio]')); - for (var i = 0, len = radios.length; i < len; i++) { - if (radios[i].checked) { - this.options.callback(parseInt(radios[i].value)); - break; - } - } - }, this) - .on(form['clear'], 'click', function(evt) { - L$1.DomEvent.stop(evt); - this.options.clear(); - }, this); - - L$1.DomEvent - .disableClickPropagation(this._container) - .disableScrollPropagation(this._container); - return this._container; - } - - }); - - function DEFAULT_COMPARE (a, b) { return a > b ? 1 : a < b ? -1 : 0; } - - var SplayTree = function SplayTree(compare, noDuplicates) { - if ( compare === void 0 ) compare = DEFAULT_COMPARE; - if ( noDuplicates === void 0 ) noDuplicates = false; - - this._compare = compare; - this._root = null; - this._size = 0; - this._noDuplicates = !!noDuplicates; - }; - - var prototypeAccessors = { size: { configurable: true } }; - - - SplayTree.prototype.rotateLeft = function rotateLeft (x) { - var y = x.right; - if (y) { - x.right = y.left; - if (y.left) { y.left.parent = x; } - y.parent = x.parent; - } - - if (!x.parent) { this._root = y; } - else if (x === x.parent.left) { x.parent.left = y; } - else { x.parent.right = y; } - if (y) { y.left = x; } - x.parent = y; - }; - - - SplayTree.prototype.rotateRight = function rotateRight (x) { - var y = x.left; - if (y) { - x.left = y.right; - if (y.right) { y.right.parent = x; } - y.parent = x.parent; - } - - if (!x.parent) { this._root = y; } - else if(x === x.parent.left) { x.parent.left = y; } - else { x.parent.right = y; } - if (y) { y.right = x; } - x.parent = y; - }; - - - SplayTree.prototype._splay = function _splay (x) { - while (x.parent) { - var p = x.parent; - if (!p.parent) { - if (p.left === x) { this.rotateRight(p); } - else { this.rotateLeft(p); } - } else if (p.left === x && p.parent.left === p) { - this.rotateRight(p.parent); - this.rotateRight(p); - } else if (p.right === x && p.parent.right === p) { - this.rotateLeft(p.parent); - this.rotateLeft(p); - } else if (p.left === x && p.parent.right === p) { - this.rotateRight(p); - this.rotateLeft(p); - } else { - this.rotateLeft(p); - this.rotateRight(p); - } - } - }; - - - SplayTree.prototype.splay = function splay (x) { - var p, gp, ggp, l, r; - - while (x.parent) { - p = x.parent; - gp = p.parent; - - if (gp && gp.parent) { - ggp = gp.parent; - if (ggp.left === gp) { ggp.left= x; } - else { ggp.right = x; } - x.parent = ggp; - } else { - x.parent = null; - this._root = x; - } - - l = x.left; r = x.right; - - if (x === p.left) { // left - if (gp) { - if (gp.left === p) { - /* zig-zig */ - if (p.right) { - gp.left = p.right; - gp.left.parent = gp; - } else { gp.left = null; } - - p.right = gp; - gp.parent = p; - } else { - /* zig-zag */ - if (l) { - gp.right = l; - l.parent = gp; - } else { gp.right = null; } - - x.left = gp; - gp.parent = x; - } - } - if (r) { - p.left = r; - r.parent = p; - } else { p.left = null; } - - x.right= p; - p.parent = x; - } else { // right - if (gp) { - if (gp.right === p) { - /* zig-zig */ - if (p.left) { - gp.right = p.left; - gp.right.parent = gp; - } else { gp.right = null; } - - p.left = gp; - gp.parent = p; - } else { - /* zig-zag */ - if (r) { - gp.left = r; - r.parent = gp; - } else { gp.left = null; } - - x.right = gp; - gp.parent = x; - } - } - if (l) { - p.right = l; - l.parent = p; - } else { p.right = null; } - - x.left = p; - p.parent = x; - } - } - }; - - - SplayTree.prototype.replace = function replace (u, v) { - if (!u.parent) { this._root = v; } - else if (u === u.parent.left) { u.parent.left = v; } - else { u.parent.right = v; } - if (v) { v.parent = u.parent; } - }; - - - SplayTree.prototype.minNode = function minNode (u) { - if ( u === void 0 ) u = this._root; - - if (u) { while (u.left) { u = u.left; } } - return u; - }; - - - SplayTree.prototype.maxNode = function maxNode (u) { - if ( u === void 0 ) u = this._root; - - if (u) { while (u.right) { u = u.right; } } - return u; - }; - - - SplayTree.prototype.insert = function insert (key, data) { - var z = this._root; - var p = null; - var comp = this._compare; - var cmp; - - if (this._noDuplicates) { - while (z) { - p = z; - cmp = comp(z.key, key); - if (cmp === 0) { return; } - else if (comp(z.key, key) < 0) { z = z.right; } - else { z = z.left; } - } - } else { - while (z) { - p = z; - if (comp(z.key, key) < 0) { z = z.right; } - else { z = z.left; } - } - } - - z = { key: key, data: data, left: null, right: null, parent: p }; - - if (!p) { this._root = z; } - else if (comp(p.key, z.key) < 0) { p.right = z; } - else { p.left= z; } - - this.splay(z); - this._size++; - return z; - }; - - - SplayTree.prototype.find = function find (key) { - var z = this._root; - var comp = this._compare; - while (z) { - var cmp = comp(z.key, key); - if (cmp < 0) { z = z.right; } - else if (cmp > 0) { z = z.left; } - else { return z; } - } - return null; - }; - - /** - * Whether the tree contains a node with the given key - * @param{Key} key - * @return {boolean} true/false - */ - SplayTree.prototype.contains = function contains (key) { - var node = this._root; - var comparator = this._compare; - while (node){ - var cmp = comparator(key, node.key); - if (cmp === 0) { return true; } - else if (cmp < 0) { node = node.left; } - else { node = node.right; } - } - - return false; - }; - - - SplayTree.prototype.remove = function remove (key) { - var z = this.find(key); - - if (!z) { return false; } - - this.splay(z); - - if (!z.left) { this.replace(z, z.right); } - else if (!z.right) { this.replace(z, z.left); } - else { - var y = this.minNode(z.right); - if (y.parent !== z) { - this.replace(y, y.right); - y.right = z.right; - y.right.parent = y; - } - this.replace(z, y); - y.left = z.left; - y.left.parent = y; - } - - this._size--; - return true; - }; - - - SplayTree.prototype.removeNode = function removeNode (z) { - if (!z) { return false; } - - this.splay(z); - - if (!z.left) { this.replace(z, z.right); } - else if (!z.right) { this.replace(z, z.left); } - else { - var y = this.minNode(z.right); - if (y.parent !== z) { - this.replace(y, y.right); - y.right = z.right; - y.right.parent = y; - } - this.replace(z, y); - y.left = z.left; - y.left.parent = y; - } - - this._size--; - return true; - }; - - - SplayTree.prototype.erase = function erase (key) { - var z = this.find(key); - if (!z) { return; } - - this.splay(z); - - var s = z.left; - var t = z.right; - - var sMax = null; - if (s) { - s.parent = null; - sMax = this.maxNode(s); - this.splay(sMax); - this._root = sMax; - } - if (t) { - if (s) { sMax.right = t; } - else { this._root = t; } - t.parent = sMax; - } - - this._size--; - }; - - /** - * Removes and returns the node with smallest key - * @return {?Node} - */ - SplayTree.prototype.pop = function pop () { - var node = this._root, returnValue = null; - if (node) { - while (node.left) { node = node.left; } - returnValue = { key: node.key, data: node.data }; - this.remove(node.key); - } - return returnValue; - }; - - - /* eslint-disable class-methods-use-this */ - - /** - * Successor node - * @param{Node} node - * @return {?Node} - */ - SplayTree.prototype.next = function next (node) { - var successor = node; - if (successor) { - if (successor.right) { - successor = successor.right; - while (successor && successor.left) { successor = successor.left; } - } else { - successor = node.parent; - while (successor && successor.right === node) { - node = successor; successor = successor.parent; - } - } - } - return successor; - }; - - - /** - * Predecessor node - * @param{Node} node - * @return {?Node} - */ - SplayTree.prototype.prev = function prev (node) { - var predecessor = node; - if (predecessor) { - if (predecessor.left) { - predecessor = predecessor.left; - while (predecessor && predecessor.right) { predecessor = predecessor.right; } - } else { - predecessor = node.parent; - while (predecessor && predecessor.left === node) { - node = predecessor; - predecessor = predecessor.parent; - } - } - } - return predecessor; - }; - /* eslint-enable class-methods-use-this */ - - - /** - * @param{forEachCallback} callback - * @return {SplayTree} - */ - SplayTree.prototype.forEach = function forEach (callback) { - var current = this._root; - var s = [], done = false, i = 0; - - while (!done) { - // Reach the left most Node of the current Node - if (current) { - // Place pointer to a tree node on the stack - // before traversing the node's left subtree - s.push(current); - current = current.left; - } else { - // BackTrack from the empty subtree and visit the Node - // at the top of the stack; however, if the stack is - // empty you are done - if (s.length > 0) { - current = s.pop(); - callback(current, i++); - - // We have visited the node and its left - // subtree. Now, it's right subtree's turn - current = current.right; - } else { done = true; } - } - } - return this; - }; - - - /** - * Walk key range from `low` to `high`. Stops if `fn` returns a value. - * @param{Key} low - * @param{Key} high - * @param{Function} fn - * @param{*?} ctx - * @return {SplayTree} - */ - SplayTree.prototype.range = function range (low, high, fn, ctx) { - var Q = []; - var compare = this._compare; - var node = this._root, cmp; - - while (Q.length !== 0 || node) { - if (node) { - Q.push(node); - node = node.left; - } else { - node = Q.pop(); - cmp = compare(node.key, high); - if (cmp > 0) { - break; - } else if (compare(node.key, low) >= 0) { - if (fn.call(ctx, node)) { return this; } // stop if smth is returned - } - node = node.right; - } - } - return this; - }; - - /** - * Returns all keys in order - * @return {Array} - */ - SplayTree.prototype.keys = function keys () { - var current = this._root; - var s = [], r = [], done = false; - - while (!done) { - if (current) { - s.push(current); - current = current.left; - } else { - if (s.length > 0) { - current = s.pop(); - r.push(current.key); - current = current.right; - } else { done = true; } - } - } - return r; - }; - - - /** - * Returns `data` fields of all nodes in order. - * @return {Array} - */ - SplayTree.prototype.values = function values () { - var current = this._root; - var s = [], r = [], done = false; - - while (!done) { - if (current) { - s.push(current); - current = current.left; - } else { - if (s.length > 0) { - current = s.pop(); - r.push(current.data); - current = current.right; - } else { done = true; } - } - } - return r; - }; - - - /** - * Returns node at given index - * @param{number} index - * @return {?Node} - */ - SplayTree.prototype.at = function at (index) { - // removed after a consideration, more misleading than useful - // index = index % this.size; - // if (index < 0) index = this.size - index; - - var current = this._root; - var s = [], done = false, i = 0; - - while (!done) { - if (current) { - s.push(current); - current = current.left; - } else { - if (s.length > 0) { - current = s.pop(); - if (i === index) { return current; } - i++; - current = current.right; - } else { done = true; } - } - } - return null; - }; - - /** - * Bulk-load items. Both array have to be same size - * @param{Array} keys - * @param{Array}[values] - * @param{Boolean} [presort=false] Pre-sort keys and values, using - * tree's comparator. Sorting is done - * in-place - * @return {AVLTree} - */ - SplayTree.prototype.load = function load (keys, values, presort) { - if ( keys === void 0 ) keys = []; - if ( values === void 0 ) values = []; - if ( presort === void 0 ) presort = false; - - if (this._size !== 0) { throw new Error('bulk-load: tree is not empty'); } - var size = keys.length; - if (presort) { sort(keys, values, 0, size - 1, this._compare); } - this._root = loadRecursive(null, keys, values, 0, size); - this._size = size; - return this; - }; - - - SplayTree.prototype.min = function min () { - var node = this.minNode(this._root); - if (node) { return node.key; } - else { return null; } - }; - - - SplayTree.prototype.max = function max () { - var node = this.maxNode(this._root); - if (node) { return node.key; } - else { return null; } - }; - - SplayTree.prototype.isEmpty = function isEmpty () { return this._root === null; }; - prototypeAccessors.size.get = function () { return this._size; }; - - - /** - * Create a tree and load it with items - * @param{Array} keys - * @param{Array?} [values] - - * @param{Function?} [comparator] - * @param{Boolean?} [presort=false] Pre-sort keys and values, using - * tree's comparator. Sorting is done - * in-place - * @param{Boolean?} [noDuplicates=false] Allow duplicates - * @return {SplayTree} - */ - SplayTree.createTree = function createTree (keys, values, comparator, presort, noDuplicates) { - return new SplayTree(comparator, noDuplicates).load(keys, values, presort); - }; - - Object.defineProperties( SplayTree.prototype, prototypeAccessors ); - - - function loadRecursive (parent, keys, values, start, end) { - var size = end - start; - if (size > 0) { - var middle = start + Math.floor(size / 2); - var key = keys[middle]; - var data = values[middle]; - var node = { key: key, data: data, parent: parent }; - node.left = loadRecursive(node, keys, values, start, middle); - node.right = loadRecursive(node, keys, values, middle + 1, end); - return node; - } - return null; - } - - - function sort(keys, values, left, right, compare) { - if (left >= right) { return; } - - var pivot = keys[(left + right) >> 1]; - var i = left - 1; - var j = right + 1; - - while (true) { - do { i++; } while (compare(keys[i], pivot) < 0); - do { j--; } while (compare(keys[j], pivot) > 0); - if (i >= j) { break; } - - var tmp = keys[i]; - keys[i] = keys[j]; - keys[j] = tmp; - - tmp = values[i]; - values[i] = values[j]; - values[j] = tmp; - } - - sort(keys, values, left, j, compare); - sort(keys, values, j + 1, right, compare); - } - - var NORMAL = 0; - var NON_CONTRIBUTING = 1; - var SAME_TRANSITION = 2; - var DIFFERENT_TRANSITION = 3; - - var INTERSECTION = 0; - var UNION = 1; - var DIFFERENCE = 2; - var XOR = 3; - - /** - * @param {SweepEvent} event - * @param {SweepEvent} prev - * @param {Operation} operation - */ - function computeFields (event, prev, operation) { - // compute inOut and otherInOut fields - if (prev === null) { - event.inOut = false; - event.otherInOut = true; - - // previous line segment in sweepline belongs to the same polygon - } else { - if (event.isSubject === prev.isSubject) { - event.inOut = !prev.inOut; - event.otherInOut = prev.otherInOut; - - // previous line segment in sweepline belongs to the clipping polygon - } else { - event.inOut = !prev.otherInOut; - event.otherInOut = prev.isVertical() ? !prev.inOut : prev.inOut; - } - - // compute prevInResult field - if (prev) { - event.prevInResult = (!inResult(prev, operation) || prev.isVertical()) - ? prev.prevInResult : prev; - } - } - - // check if the line segment belongs to the Boolean operation - var isInResult = inResult(event, operation); - if (isInResult) { - event.resultTransition = determineResultTransition(event, operation); - } else { - event.resultTransition = 0; - } - } - - - /* eslint-disable indent */ - function inResult(event, operation) { - switch (event.type) { - case NORMAL: - switch (operation) { - case INTERSECTION: - return !event.otherInOut; - case UNION: - return event.otherInOut; - case DIFFERENCE: - // return (event.isSubject && !event.otherInOut) || - // (!event.isSubject && event.otherInOut); - return (event.isSubject && event.otherInOut) || - (!event.isSubject && !event.otherInOut); - case XOR: - return true; - } - break; - case SAME_TRANSITION: - return operation === INTERSECTION || operation === UNION; - case DIFFERENT_TRANSITION: - return operation === DIFFERENCE; - case NON_CONTRIBUTING: - return false; - } - return false; - } - /* eslint-enable indent */ - - - function determineResultTransition(event, operation) { - var thisIn = !event.inOut; - var thatIn = !event.otherInOut; - - var isIn; - switch (operation) { - case INTERSECTION: - isIn = thisIn && thatIn; break; - case UNION: - isIn = thisIn || thatIn; break; - case XOR: - isIn = thisIn ^ thatIn; break; - case DIFFERENCE: - if (event.isSubject) { - isIn = thisIn && !thatIn; - } else { - isIn = thatIn && !thisIn; - } - break; - } - return isIn ? +1 : -1; - } - - var SweepEvent = function SweepEvent (point, left, otherEvent, isSubject, edgeType) { - - /** - * Is left endpoint? - * @type {Boolean} - */ - this.left = left; - - /** - * @type {Array.} - */ - this.point = point; - - /** - * Other edge reference - * @type {SweepEvent} - */ - this.otherEvent = otherEvent; - - /** - * Belongs to source or clipping polygon - * @type {Boolean} - */ - this.isSubject = isSubject; - - /** - * Edge contribution type - * @type {Number} - */ - this.type = edgeType || NORMAL; - - - /** - * In-out transition for the sweepline crossing polygon - * @type {Boolean} - */ - this.inOut = false; - - - /** - * @type {Boolean} - */ - this.otherInOut = false; - - /** - * Previous event in result? - * @type {SweepEvent} - */ - this.prevInResult = null; - - /** - * Type of result transition (0 = not in result, +1 = out-in, -1, in-out) - * @type {Number} - */ - this.resultTransition = 0; - - // connection step - - /** - * @type {Number} - */ - this.otherPos = -1; - - /** - * @type {Number} - */ - this.outputContourId = -1; - - this.isExteriorRing = true; // TODO: Looks unused, remove? - }; - - var prototypeAccessors$1 = { inResult: { configurable: true } }; - - - /** - * @param{Array.}p - * @return {Boolean} - */ - SweepEvent.prototype.isBelow = function isBelow (p) { - var p0 = this.point, p1 = this.otherEvent.point; - return this.left - ? (p0[0] - p[0]) * (p1[1] - p[1]) - (p1[0] - p[0]) * (p0[1] - p[1]) > 0 - // signedArea(this.point, this.otherEvent.point, p) > 0 : - : (p1[0] - p[0]) * (p0[1] - p[1]) - (p0[0] - p[0]) * (p1[1] - p[1]) > 0; - //signedArea(this.otherEvent.point, this.point, p) > 0; - }; - - - /** - * @param{Array.}p - * @return {Boolean} - */ - SweepEvent.prototype.isAbove = function isAbove (p) { - return !this.isBelow(p); - }; - - - /** - * @return {Boolean} - */ - SweepEvent.prototype.isVertical = function isVertical () { - return this.point[0] === this.otherEvent.point[0]; - }; - - - /** - * Does event belong to result? - * @return {Boolean} - */ - prototypeAccessors$1.inResult.get = function () { - return this.resultTransition !== 0; - }; - - - SweepEvent.prototype.clone = function clone () { - var copy = new SweepEvent( - this.point, this.left, this.otherEvent, this.isSubject, this.type); - - copy.contourId = this.contourId; - copy.resultTransition = this.resultTransition; - copy.prevInResult = this.prevInResult; - copy.isExteriorRing = this.isExteriorRing; - copy.inOut = this.inOut; - copy.otherInOut = this.otherInOut; - - return copy; - }; - - Object.defineProperties( SweepEvent.prototype, prototypeAccessors$1 ); - - function equals(p1, p2) { - if (p1[0] === p2[0]) { - if (p1[1] === p2[1]) { - return true; - } else { - return false; - } - } - return false; - } - - // const EPSILON = 1e-9; - // const abs = Math.abs; - // TODO https://github.com/w8r/martinez/issues/6#issuecomment-262847164 - // Precision problem. - // - // module.exports = function equals(p1, p2) { - // return abs(p1[0] - p2[0]) <= EPSILON && abs(p1[1] - p2[1]) <= EPSILON; - // }; - - var epsilon = 1.1102230246251565e-16; - var splitter = 134217729; - var resulterrbound = (3 + 8 * epsilon) * epsilon; - - // fast_expansion_sum_zeroelim routine from oritinal code - function sum(elen, e, flen, f, h) { - var Q, Qnew, hh, bvirt; - var enow = e[0]; - var fnow = f[0]; - var eindex = 0; - var findex = 0; - if ((fnow > enow) === (fnow > -enow)) { - Q = enow; - enow = e[++eindex]; - } else { - Q = fnow; - fnow = f[++findex]; - } - var hindex = 0; - if (eindex < elen && findex < flen) { - if ((fnow > enow) === (fnow > -enow)) { - Qnew = enow + Q; - hh = Q - (Qnew - enow); - enow = e[++eindex]; - } else { - Qnew = fnow + Q; - hh = Q - (Qnew - fnow); - fnow = f[++findex]; - } - Q = Qnew; - if (hh !== 0) { - h[hindex++] = hh; - } - while (eindex < elen && findex < flen) { - if ((fnow > enow) === (fnow > -enow)) { - Qnew = Q + enow; - bvirt = Qnew - Q; - hh = Q - (Qnew - bvirt) + (enow - bvirt); - enow = e[++eindex]; - } else { - Qnew = Q + fnow; - bvirt = Qnew - Q; - hh = Q - (Qnew - bvirt) + (fnow - bvirt); - fnow = f[++findex]; - } - Q = Qnew; - if (hh !== 0) { - h[hindex++] = hh; - } - } - } - while (eindex < elen) { - Qnew = Q + enow; - bvirt = Qnew - Q; - hh = Q - (Qnew - bvirt) + (enow - bvirt); - enow = e[++eindex]; - Q = Qnew; - if (hh !== 0) { - h[hindex++] = hh; - } - } - while (findex < flen) { - Qnew = Q + fnow; - bvirt = Qnew - Q; - hh = Q - (Qnew - bvirt) + (fnow - bvirt); - fnow = f[++findex]; - Q = Qnew; - if (hh !== 0) { - h[hindex++] = hh; - } - } - if (Q !== 0 || hindex === 0) { - h[hindex++] = Q; - } - return hindex; - } - - function estimate(elen, e) { - var Q = e[0]; - for (var i = 1; i < elen; i++) { Q += e[i]; } - return Q; - } - - function vec(n) { - return new Float64Array(n); - } - - var ccwerrboundA = (3 + 16 * epsilon) * epsilon; - var ccwerrboundB = (2 + 12 * epsilon) * epsilon; - var ccwerrboundC = (9 + 64 * epsilon) * epsilon * epsilon; - - var B = vec(4); - var C1 = vec(8); - var C2 = vec(12); - var D = vec(16); - var u = vec(4); - - function orient2dadapt(ax, ay, bx, by, cx, cy, detsum) { - var acxtail, acytail, bcxtail, bcytail; - var bvirt, c, ahi, alo, bhi, blo, _i, _j, _0, s1, s0, t1, t0, u3; - - var acx = ax - cx; - var bcx = bx - cx; - var acy = ay - cy; - var bcy = by - cy; - - s1 = acx * bcy; - c = splitter * acx; - ahi = c - (c - acx); - alo = acx - ahi; - c = splitter * bcy; - bhi = c - (c - bcy); - blo = bcy - bhi; - s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo); - t1 = acy * bcx; - c = splitter * acy; - ahi = c - (c - acy); - alo = acy - ahi; - c = splitter * bcx; - bhi = c - (c - bcx); - blo = bcx - bhi; - t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo); - _i = s0 - t0; - bvirt = s0 - _i; - B[0] = s0 - (_i + bvirt) + (bvirt - t0); - _j = s1 + _i; - bvirt = _j - s1; - _0 = s1 - (_j - bvirt) + (_i - bvirt); - _i = _0 - t1; - bvirt = _0 - _i; - B[1] = _0 - (_i + bvirt) + (bvirt - t1); - u3 = _j + _i; - bvirt = u3 - _j; - B[2] = _j - (u3 - bvirt) + (_i - bvirt); - B[3] = u3; - - var det = estimate(4, B); - var errbound = ccwerrboundB * detsum; - if (det >= errbound || -det >= errbound) { - return det; - } - - bvirt = ax - acx; - acxtail = ax - (acx + bvirt) + (bvirt - cx); - bvirt = bx - bcx; - bcxtail = bx - (bcx + bvirt) + (bvirt - cx); - bvirt = ay - acy; - acytail = ay - (acy + bvirt) + (bvirt - cy); - bvirt = by - bcy; - bcytail = by - (bcy + bvirt) + (bvirt - cy); - - if (acxtail === 0 && acytail === 0 && bcxtail === 0 && bcytail === 0) { - return det; - } - - errbound = ccwerrboundC * detsum + resulterrbound * Math.abs(det); - det += (acx * bcytail + bcy * acxtail) - (acy * bcxtail + bcx * acytail); - if (det >= errbound || -det >= errbound) { return det; } - - s1 = acxtail * bcy; - c = splitter * acxtail; - ahi = c - (c - acxtail); - alo = acxtail - ahi; - c = splitter * bcy; - bhi = c - (c - bcy); - blo = bcy - bhi; - s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo); - t1 = acytail * bcx; - c = splitter * acytail; - ahi = c - (c - acytail); - alo = acytail - ahi; - c = splitter * bcx; - bhi = c - (c - bcx); - blo = bcx - bhi; - t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo); - _i = s0 - t0; - bvirt = s0 - _i; - u[0] = s0 - (_i + bvirt) + (bvirt - t0); - _j = s1 + _i; - bvirt = _j - s1; - _0 = s1 - (_j - bvirt) + (_i - bvirt); - _i = _0 - t1; - bvirt = _0 - _i; - u[1] = _0 - (_i + bvirt) + (bvirt - t1); - u3 = _j + _i; - bvirt = u3 - _j; - u[2] = _j - (u3 - bvirt) + (_i - bvirt); - u[3] = u3; - var C1len = sum(4, B, 4, u, C1); - - s1 = acx * bcytail; - c = splitter * acx; - ahi = c - (c - acx); - alo = acx - ahi; - c = splitter * bcytail; - bhi = c - (c - bcytail); - blo = bcytail - bhi; - s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo); - t1 = acy * bcxtail; - c = splitter * acy; - ahi = c - (c - acy); - alo = acy - ahi; - c = splitter * bcxtail; - bhi = c - (c - bcxtail); - blo = bcxtail - bhi; - t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo); - _i = s0 - t0; - bvirt = s0 - _i; - u[0] = s0 - (_i + bvirt) + (bvirt - t0); - _j = s1 + _i; - bvirt = _j - s1; - _0 = s1 - (_j - bvirt) + (_i - bvirt); - _i = _0 - t1; - bvirt = _0 - _i; - u[1] = _0 - (_i + bvirt) + (bvirt - t1); - u3 = _j + _i; - bvirt = u3 - _j; - u[2] = _j - (u3 - bvirt) + (_i - bvirt); - u[3] = u3; - var C2len = sum(C1len, C1, 4, u, C2); - - s1 = acxtail * bcytail; - c = splitter * acxtail; - ahi = c - (c - acxtail); - alo = acxtail - ahi; - c = splitter * bcytail; - bhi = c - (c - bcytail); - blo = bcytail - bhi; - s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo); - t1 = acytail * bcxtail; - c = splitter * acytail; - ahi = c - (c - acytail); - alo = acytail - ahi; - c = splitter * bcxtail; - bhi = c - (c - bcxtail); - blo = bcxtail - bhi; - t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo); - _i = s0 - t0; - bvirt = s0 - _i; - u[0] = s0 - (_i + bvirt) + (bvirt - t0); - _j = s1 + _i; - bvirt = _j - s1; - _0 = s1 - (_j - bvirt) + (_i - bvirt); - _i = _0 - t1; - bvirt = _0 - _i; - u[1] = _0 - (_i + bvirt) + (bvirt - t1); - u3 = _j + _i; - bvirt = u3 - _j; - u[2] = _j - (u3 - bvirt) + (_i - bvirt); - u[3] = u3; - var Dlen = sum(C2len, C2, 4, u, D); - - return D[Dlen - 1]; - } - - function orient2d(ax, ay, bx, by, cx, cy) { - var detleft = (ay - cy) * (bx - cx); - var detright = (ax - cx) * (by - cy); - var det = detleft - detright; - - if (detleft === 0 || detright === 0 || (detleft > 0) !== (detright > 0)) { return det; } - - var detsum = Math.abs(detleft + detright); - if (Math.abs(det) >= ccwerrboundA * detsum) { return det; } - - return -orient2dadapt(ax, ay, bx, by, cx, cy, detsum); - } - - /** - * Signed area of the triangle (p0, p1, p2) - * @param {Array.} p0 - * @param {Array.} p1 - * @param {Array.} p2 - * @return {Number} - */ - function signedArea(p0, p1, p2) { - var res = orient2d(p0[0], p0[1], p1[0], p1[1], p2[0], p2[1]); - if (res > 0) { return -1; } - if (res < 0) { return 1; } - return 0; - } - - /** - * @param {SweepEvent} e1 - * @param {SweepEvent} e2 - * @return {Number} - */ - function compareEvents(e1, e2) { - var p1 = e1.point; - var p2 = e2.point; - - // Different x-coordinate - if (p1[0] > p2[0]) { return 1; } - if (p1[0] < p2[0]) { return -1; } - - // Different points, but same x-coordinate - // Event with lower y-coordinate is processed first - if (p1[1] !== p2[1]) { return p1[1] > p2[1] ? 1 : -1; } - - return specialCases(e1, e2, p1); - } - - - /* eslint-disable no-unused-vars */ - function specialCases(e1, e2, p1, p2) { - // Same coordinates, but one is a left endpoint and the other is - // a right endpoint. The right endpoint is processed first - if (e1.left !== e2.left) - { return e1.left ? 1 : -1; } - - // const p2 = e1.otherEvent.point, p3 = e2.otherEvent.point; - // const sa = (p1[0] - p3[0]) * (p2[1] - p3[1]) - (p2[0] - p3[0]) * (p1[1] - p3[1]) - // Same coordinates, both events - // are left endpoints or right endpoints. - // not collinear - if (signedArea(p1, e1.otherEvent.point, e2.otherEvent.point) !== 0) { - // the event associate to the bottom segment is processed first - return (!e1.isBelow(e2.otherEvent.point)) ? 1 : -1; - } - - return (!e1.isSubject && e2.isSubject) ? 1 : -1; - } - /* eslint-enable no-unused-vars */ - - /** - * @param {SweepEvent} se - * @param {Array.} p - * @param {Queue} queue - * @return {Queue} - */ - function divideSegment(se, p, queue) { - var r = new SweepEvent(p, false, se, se.isSubject); - var l = new SweepEvent(p, true, se.otherEvent, se.isSubject); - - /* eslint-disable no-console */ - if (equals(se.point, se.otherEvent.point)) { - console.warn('what is that, a collapsed segment?', se); - } - /* eslint-enable no-console */ - - r.contourId = l.contourId = se.contourId; - - // avoid a rounding error. The left event would be processed after the right event - if (compareEvents(l, se.otherEvent) > 0) { - se.otherEvent.left = true; - l.left = false; - } - - // avoid a rounding error. The left event would be processed after the right event - // if (compareEvents(se, r) > 0) {} - - se.otherEvent.otherEvent = l; - se.otherEvent = r; - - queue.push(l); - queue.push(r); - - return queue; - } - - //const EPS = 1e-9; - - /** - * Finds the magnitude of the cross product of two vectors (if we pretend - * they're in three dimensions) - * - * @param {Object} a First vector - * @param {Object} b Second vector - * @private - * @returns {Number} The magnitude of the cross product - */ - function crossProduct(a, b) { - return (a[0] * b[1]) - (a[1] * b[0]); - } - - /** - * Finds the dot product of two vectors. - * - * @param {Object} a First vector - * @param {Object} b Second vector - * @private - * @returns {Number} The dot product - */ - function dotProduct(a, b) { - return (a[0] * b[0]) + (a[1] * b[1]); - } - - /** - * Finds the intersection (if any) between two line segments a and b, given the - * line segments' end points a1, a2 and b1, b2. - * - * This algorithm is based on Schneider and Eberly. - * http://www.cimec.org.ar/~ncalvo/Schneider_Eberly.pdf - * Page 244. - * - * @param {Array.} a1 point of first line - * @param {Array.} a2 point of first line - * @param {Array.} b1 point of second line - * @param {Array.} b2 point of second line - * @param {Boolean=} noEndpointTouch whether to skip single touchpoints - * (meaning connected segments) as - * intersections - * @returns {Array.>|Null} If the lines intersect, the point of - * intersection. If they overlap, the two end points of the overlapping segment. - * Otherwise, null. - */ - function intersection (a1, a2, b1, b2, noEndpointTouch) { - // The algorithm expects our lines in the form P + sd, where P is a point, - // s is on the interval [0, 1], and d is a vector. - // We are passed two points. P can be the first point of each pair. The - // vector, then, could be thought of as the distance (in x and y components) - // from the first point to the second point. - // So first, let's make our vectors: - var va = [a2[0] - a1[0], a2[1] - a1[1]]; - var vb = [b2[0] - b1[0], b2[1] - b1[1]]; - // We also define a function to convert back to regular point form: - - /* eslint-disable arrow-body-style */ - - function toPoint(p, s, d) { - return [ - p[0] + s * d[0], - p[1] + s * d[1] - ]; - } - - /* eslint-enable arrow-body-style */ - - // The rest is pretty much a straight port of the algorithm. - var e = [b1[0] - a1[0], b1[1] - a1[1]]; - var kross = crossProduct(va, vb); - var sqrKross = kross * kross; - var sqrLenA = dotProduct(va, va); - //const sqrLenB = dotProduct(vb, vb); - - // Check for line intersection. This works because of the properties of the - // cross product -- specifically, two vectors are parallel if and only if the - // cross product is the 0 vector. The full calculation involves relative error - // to account for possible very small line segments. See Schneider & Eberly - // for details. - if (sqrKross > 0/* EPS * sqrLenB * sqLenA */) { - // If they're not parallel, then (because these are line segments) they - // still might not actually intersect. This code checks that the - // intersection point of the lines is actually on both line segments. - var s = crossProduct(e, vb) / kross; - if (s < 0 || s > 1) { - // not on line segment a - return null; - } - var t = crossProduct(e, va) / kross; - if (t < 0 || t > 1) { - // not on line segment b - return null; - } - if (s === 0 || s === 1) { - // on an endpoint of line segment a - return noEndpointTouch ? null : [toPoint(a1, s, va)]; - } - if (t === 0 || t === 1) { - // on an endpoint of line segment b - return noEndpointTouch ? null : [toPoint(b1, t, vb)]; - } - return [toPoint(a1, s, va)]; - } - - // If we've reached this point, then the lines are either parallel or the - // same, but the segments could overlap partially or fully, or not at all. - // So we need to find the overlap, if any. To do that, we can use e, which is - // the (vector) difference between the two initial points. If this is parallel - // with the line itself, then the two lines are the same line, and there will - // be overlap. - //const sqrLenE = dotProduct(e, e); - kross = crossProduct(e, va); - sqrKross = kross * kross; - - if (sqrKross > 0 /* EPS * sqLenB * sqLenE */) { - // Lines are just parallel, not the same. No overlap. - return null; - } - - var sa = dotProduct(va, e) / sqrLenA; - var sb = sa + dotProduct(va, vb) / sqrLenA; - var smin = Math.min(sa, sb); - var smax = Math.max(sa, sb); - - // this is, essentially, the FindIntersection acting on floats from - // Schneider & Eberly, just inlined into this function. - if (smin <= 1 && smax >= 0) { - - // overlap on an end point - if (smin === 1) { - return noEndpointTouch ? null : [toPoint(a1, smin > 0 ? smin : 0, va)]; - } - - if (smax === 0) { - return noEndpointTouch ? null : [toPoint(a1, smax < 1 ? smax : 1, va)]; - } - - if (noEndpointTouch && smin === 0 && smax === 1) { return null; } - - // There's overlap on a segment -- two points of intersection. Return both. - return [ - toPoint(a1, smin > 0 ? smin : 0, va), - toPoint(a1, smax < 1 ? smax : 1, va) - ]; - } - - return null; - } - - /** - * @param {SweepEvent} se1 - * @param {SweepEvent} se2 - * @param {Queue} queue - * @return {Number} - */ - function possibleIntersection (se1, se2, queue) { - // that disallows self-intersecting polygons, - // did cost us half a day, so I'll leave it - // out of respect - // if (se1.isSubject === se2.isSubject) return; - var inter = intersection( - se1.point, se1.otherEvent.point, - se2.point, se2.otherEvent.point - ); - - var nintersections = inter ? inter.length : 0; - if (nintersections === 0) { return 0; } // no intersection - - // the line segments intersect at an endpoint of both line segments - if ((nintersections === 1) && - (equals(se1.point, se2.point) || - equals(se1.otherEvent.point, se2.otherEvent.point))) { - return 0; - } - - if (nintersections === 2 && se1.isSubject === se2.isSubject) { - // if(se1.contourId === se2.contourId){ - // console.warn('Edges of the same polygon overlap', - // se1.point, se1.otherEvent.point, se2.point, se2.otherEvent.point); - // } - //throw new Error('Edges of the same polygon overlap'); - return 0; - } - - // The line segments associated to se1 and se2 intersect - if (nintersections === 1) { - - // if the intersection point is not an endpoint of se1 - if (!equals(se1.point, inter[0]) && !equals(se1.otherEvent.point, inter[0])) { - divideSegment(se1, inter[0], queue); - } - - // if the intersection point is not an endpoint of se2 - if (!equals(se2.point, inter[0]) && !equals(se2.otherEvent.point, inter[0])) { - divideSegment(se2, inter[0], queue); - } - return 1; - } - - // The line segments associated to se1 and se2 overlap - var events = []; - var leftCoincide = false; - var rightCoincide = false; - - if (equals(se1.point, se2.point)) { - leftCoincide = true; // linked - } else if (compareEvents(se1, se2) === 1) { - events.push(se2, se1); - } else { - events.push(se1, se2); - } - - if (equals(se1.otherEvent.point, se2.otherEvent.point)) { - rightCoincide = true; - } else if (compareEvents(se1.otherEvent, se2.otherEvent) === 1) { - events.push(se2.otherEvent, se1.otherEvent); - } else { - events.push(se1.otherEvent, se2.otherEvent); - } - - if ((leftCoincide && rightCoincide) || leftCoincide) { - // both line segments are equal or share the left endpoint - se2.type = NON_CONTRIBUTING; - se1.type = (se2.inOut === se1.inOut) - ? SAME_TRANSITION : DIFFERENT_TRANSITION; - - if (leftCoincide && !rightCoincide) { - // honestly no idea, but changing events selection from [2, 1] - // to [0, 1] fixes the overlapping self-intersecting polygons issue - divideSegment(events[1].otherEvent, events[0].point, queue); - } - return 2; - } - - // the line segments share the right endpoint - if (rightCoincide) { - divideSegment(events[0], events[1].point, queue); - return 3; - } - - // no line segment includes totally the other one - if (events[0] !== events[3].otherEvent) { - divideSegment(events[0], events[1].point, queue); - divideSegment(events[1], events[2].point, queue); - return 3; - } - - // one line segment includes the other one - divideSegment(events[0], events[1].point, queue); - divideSegment(events[3].otherEvent, events[2].point, queue); - - return 3; - } - - /** - * @param {SweepEvent} le1 - * @param {SweepEvent} le2 - * @return {Number} - */ - function compareSegments(le1, le2) { - if (le1 === le2) { return 0; } - - // Segments are not collinear - if (signedArea(le1.point, le1.otherEvent.point, le2.point) !== 0 || - signedArea(le1.point, le1.otherEvent.point, le2.otherEvent.point) !== 0) { - - // If they share their left endpoint use the right endpoint to sort - if (equals(le1.point, le2.point)) { return le1.isBelow(le2.otherEvent.point) ? -1 : 1; } - - // Different left endpoint: use the left endpoint to sort - if (le1.point[0] === le2.point[0]) { return le1.point[1] < le2.point[1] ? -1 : 1; } - - // has the line segment associated to e1 been inserted - // into S after the line segment associated to e2 ? - if (compareEvents(le1, le2) === 1) { return le2.isAbove(le1.point) ? -1 : 1; } - - // The line segment associated to e2 has been inserted - // into S after the line segment associated to e1 - return le1.isBelow(le2.point) ? -1 : 1; - } - - if (le1.isSubject === le2.isSubject) { // same polygon - var p1 = le1.point, p2 = le2.point; - if (p1[0] === p2[0] && p1[1] === p2[1]/*equals(le1.point, le2.point)*/) { - p1 = le1.otherEvent.point; p2 = le2.otherEvent.point; - if (p1[0] === p2[0] && p1[1] === p2[1]) { return 0; } - else { return le1.contourId > le2.contourId ? 1 : -1; } - } - } else { // Segments are collinear, but belong to separate polygons - return le1.isSubject ? -1 : 1; - } - - return compareEvents(le1, le2) === 1 ? 1 : -1; - } - - function subdivide(eventQueue, subject, clipping, sbbox, cbbox, operation) { - var sweepLine = new SplayTree(compareSegments); - var sortedEvents = []; - - var rightbound = Math.min(sbbox[2], cbbox[2]); - - var prev, next, begin; - - while (eventQueue.length !== 0) { - var event = eventQueue.pop(); - sortedEvents.push(event); - - // optimization by bboxes for intersection and difference goes here - if ((operation === INTERSECTION && event.point[0] > rightbound) || - (operation === DIFFERENCE && event.point[0] > sbbox[2])) { - break; - } - - if (event.left) { - next = prev = sweepLine.insert(event); - begin = sweepLine.minNode(); - - if (prev !== begin) { prev = sweepLine.prev(prev); } - else { prev = null; } - - next = sweepLine.next(next); - - var prevEvent = prev ? prev.key : null; - var prevprevEvent = (void 0); - computeFields(event, prevEvent, operation); - if (next) { - if (possibleIntersection(event, next.key, eventQueue) === 2) { - computeFields(event, prevEvent, operation); - computeFields(next.key, event, operation); - } - } - - if (prev) { - if (possibleIntersection(prev.key, event, eventQueue) === 2) { - var prevprev = prev; - if (prevprev !== begin) { prevprev = sweepLine.prev(prevprev); } - else { prevprev = null; } - - prevprevEvent = prevprev ? prevprev.key : null; - computeFields(prevEvent, prevprevEvent, operation); - computeFields(event, prevEvent, operation); - } - } - } else { - event = event.otherEvent; - next = prev = sweepLine.find(event); - - if (prev && next) { - - if (prev !== begin) { prev = sweepLine.prev(prev); } - else { prev = null; } - - next = sweepLine.next(next); - sweepLine.remove(event); - - if (next && prev) { - possibleIntersection(prev.key, next.key, eventQueue); - } - } - } - } - return sortedEvents; - } - - var Contour = function Contour() { - this.points = []; - this.holeIds = []; - this.holeOf = null; - this.depth = null; - }; - - Contour.prototype.isExterior = function isExterior () { - return this.holeOf == null; - }; - - /** - * @param {Array.} sortedEvents - * @return {Array.} - */ - function orderEvents(sortedEvents) { - var event, i, len, tmp; - var resultEvents = []; - for (i = 0, len = sortedEvents.length; i < len; i++) { - event = sortedEvents[i]; - if ((event.left && event.inResult) || - (!event.left && event.otherEvent.inResult)) { - resultEvents.push(event); - } - } - // Due to overlapping edges the resultEvents array can be not wholly sorted - var sorted = false; - while (!sorted) { - sorted = true; - for (i = 0, len = resultEvents.length; i < len; i++) { - if ((i + 1) < len && - compareEvents(resultEvents[i], resultEvents[i + 1]) === 1) { - tmp = resultEvents[i]; - resultEvents[i] = resultEvents[i + 1]; - resultEvents[i + 1] = tmp; - sorted = false; - } - } - } - - - for (i = 0, len = resultEvents.length; i < len; i++) { - event = resultEvents[i]; - event.otherPos = i; - } - - // imagine, the right event is found in the beginning of the queue, - // when his left counterpart is not marked yet - for (i = 0, len = resultEvents.length; i < len; i++) { - event = resultEvents[i]; - if (!event.left) { - tmp = event.otherPos; - event.otherPos = event.otherEvent.otherPos; - event.otherEvent.otherPos = tmp; - } - } - - return resultEvents; - } - - - /** - * @param {Number} pos - * @param {Array.} resultEvents - * @param {Object>} processed - * @return {Number} - */ - function nextPos(pos, resultEvents, processed, origPos) { - var newPos = pos + 1, - p = resultEvents[pos].point, - p1; - var length = resultEvents.length; - - if (newPos < length) - { p1 = resultEvents[newPos].point; } - - while (newPos < length && p1[0] === p[0] && p1[1] === p[1]) { - if (!processed[newPos]) { - return newPos; - } else { - newPos++; - } - if (newPos < length) { - p1 = resultEvents[newPos].point; - } - } - - newPos = pos - 1; - - while (processed[newPos] && newPos > origPos) { - newPos--; - } - - return newPos; - } - - - function initializeContourFromContext(event, contours, contourId) { - var contour = new Contour(); - if (event.prevInResult != null) { - var prevInResult = event.prevInResult; - // Note that it is valid to query the "previous in result" for its output contour id, - // because we must have already processed it (i.e., assigned an output contour id) - // in an earlier iteration, otherwise it wouldn't be possible that it is "previous in - // result". - var lowerContourId = prevInResult.outputContourId; - var lowerResultTransition = prevInResult.resultTransition; - if (lowerResultTransition > 0) { - // We are inside. Now we have to check if the thing below us is another hole or - // an exterior contour. - var lowerContour = contours[lowerContourId]; - if (lowerContour.holeOf != null) { - // The lower contour is a hole => Connect the new contour as a hole to its parent, - // and use same depth. - var parentContourId = lowerContour.holeOf; - contours[parentContourId].holeIds.push(contourId); - contour.holeOf = parentContourId; - contour.depth = contours[lowerContourId].depth; - } else { - // The lower contour is an exterior contour => Connect the new contour as a hole, - // and increment depth. - contours[lowerContourId].holeIds.push(contourId); - contour.holeOf = lowerContourId; - contour.depth = contours[lowerContourId].depth + 1; - } - } else { - // We are outside => this contour is an exterior contour of same depth. - contour.holeOf = null; - contour.depth = contours[lowerContourId].depth; - } - } else { - // There is no lower/previous contour => this contour is an exterior contour of depth 0. - contour.holeOf = null; - contour.depth = 0; - } - return contour; - } - - /** - * @param {Array.} sortedEvents - * @return {Array.<*>} polygons - */ - function connectEdges(sortedEvents) { - var i, len; - var resultEvents = orderEvents(sortedEvents); - - // "false"-filled array - var processed = {}; - var contours = []; - - var loop = function ( ) { - - if (processed[i]) { - return; - } - - var contourId = contours.length; - var contour = initializeContourFromContext(resultEvents[i], contours, contourId); - - // Helper function that combines marking an event as processed with assigning its output contour ID - var markAsProcessed = function (pos) { - processed[pos] = true; - if (pos < resultEvents.length && resultEvents[pos]) { - resultEvents[pos].outputContourId = contourId; - } - }; - - var pos = i; - var origPos = i; - - var initial = resultEvents[i].point; - contour.points.push(initial); - - /* eslint no-constant-condition: "off" */ - while (true) { - markAsProcessed(pos); - - pos = resultEvents[pos].otherPos; - - markAsProcessed(pos); - contour.points.push(resultEvents[pos].point); - - pos = nextPos(pos, resultEvents, processed, origPos); - - if (pos == origPos || pos >= resultEvents.length || !resultEvents[pos]) { - break; - } - } - - contours.push(contour); - }; - - for (i = 0, len = resultEvents.length; i < len; i++) loop( ); - - return contours; - } - - var tinyqueue = TinyQueue; - var default_1 = TinyQueue; - - function TinyQueue(data, compare) { - if (!(this instanceof TinyQueue)) { return new TinyQueue(data, compare); } - - this.data = data || []; - this.length = this.data.length; - this.compare = compare || defaultCompare; - - if (this.length > 0) { - for (var i = (this.length >> 1) - 1; i >= 0; i--) { this._down(i); } - } - } - - function defaultCompare(a, b) { - return a < b ? -1 : a > b ? 1 : 0; - } - - TinyQueue.prototype = { - - push: function (item) { - this.data.push(item); - this.length++; - this._up(this.length - 1); - }, - - pop: function () { - if (this.length === 0) { return undefined; } - - var top = this.data[0]; - this.length--; - - if (this.length > 0) { - this.data[0] = this.data[this.length]; - this._down(0); - } - this.data.pop(); - - return top; - }, - - peek: function () { - return this.data[0]; - }, - - _up: function (pos) { - var data = this.data; - var compare = this.compare; - var item = data[pos]; - - while (pos > 0) { - var parent = (pos - 1) >> 1; - var current = data[parent]; - if (compare(item, current) >= 0) { break; } - data[pos] = current; - pos = parent; - } - - data[pos] = item; - }, - - _down: function (pos) { - var data = this.data; - var compare = this.compare; - var halfLength = this.length >> 1; - var item = data[pos]; - - while (pos < halfLength) { - var left = (pos << 1) + 1; - var right = left + 1; - var best = data[left]; - - if (right < this.length && compare(data[right], best) < 0) { - left = right; - best = data[right]; - } - if (compare(best, item) >= 0) { break; } - - data[pos] = best; - pos = left; - } - - data[pos] = item; - } - }; - tinyqueue.default = default_1; - - var max = Math.max; - var min = Math.min; - - var contourId = 0; - - - function processPolygon(contourOrHole, isSubject, depth, Q, bbox, isExteriorRing) { - var i, len, s1, s2, e1, e2; - for (i = 0, len = contourOrHole.length - 1; i < len; i++) { - s1 = contourOrHole[i]; - s2 = contourOrHole[i + 1]; - e1 = new SweepEvent(s1, false, undefined, isSubject); - e2 = new SweepEvent(s2, false, e1, isSubject); - e1.otherEvent = e2; - - if (s1[0] === s2[0] && s1[1] === s2[1]) { - continue; // skip collapsed edges, or it breaks - } - - e1.contourId = e2.contourId = depth; - if (!isExteriorRing) { - e1.isExteriorRing = false; - e2.isExteriorRing = false; - } - if (compareEvents(e1, e2) > 0) { - e2.left = true; - } else { - e1.left = true; - } - - var x = s1[0], y = s1[1]; - bbox[0] = min(bbox[0], x); - bbox[1] = min(bbox[1], y); - bbox[2] = max(bbox[2], x); - bbox[3] = max(bbox[3], y); - - // Pushing it so the queue is sorted from left to right, - // with object on the left having the highest priority. - Q.push(e1); - Q.push(e2); - } - } - - - function fillQueue(subject, clipping, sbbox, cbbox, operation) { - var eventQueue = new tinyqueue(null, compareEvents); - var polygonSet, isExteriorRing, i, ii, j, jj; //, k, kk; - - for (i = 0, ii = subject.length; i < ii; i++) { - polygonSet = subject[i]; - for (j = 0, jj = polygonSet.length; j < jj; j++) { - isExteriorRing = j === 0; - if (isExteriorRing) { contourId++; } - processPolygon(polygonSet[j], true, contourId, eventQueue, sbbox, isExteriorRing); - } - } - - for (i = 0, ii = clipping.length; i < ii; i++) { - polygonSet = clipping[i]; - for (j = 0, jj = polygonSet.length; j < jj; j++) { - isExteriorRing = j === 0; - if (operation === DIFFERENCE) { isExteriorRing = false; } - if (isExteriorRing) { contourId++; } - processPolygon(polygonSet[j], false, contourId, eventQueue, cbbox, isExteriorRing); - } - } - - return eventQueue; - } - - var EMPTY = []; - - - function trivialOperation(subject, clipping, operation) { - var result = null; - if (subject.length * clipping.length === 0) { - if (operation === INTERSECTION) { - result = EMPTY; - } else if (operation === DIFFERENCE) { - result = subject; - } else if (operation === UNION || - operation === XOR) { - result = (subject.length === 0) ? clipping : subject; - } - } - return result; - } - - - function compareBBoxes(subject, clipping, sbbox, cbbox, operation) { - var result = null; - if (sbbox[0] > cbbox[2] || - cbbox[0] > sbbox[2] || - sbbox[1] > cbbox[3] || - cbbox[1] > sbbox[3]) { - if (operation === INTERSECTION) { - result = EMPTY; - } else if (operation === DIFFERENCE) { - result = subject; - } else if (operation === UNION || - operation === XOR) { - result = subject.concat(clipping); - } - } - return result; - } - - - function boolean(subject, clipping, operation) { - if (typeof subject[0][0][0] === 'number') { - subject = [subject]; - } - if (typeof clipping[0][0][0] === 'number') { - clipping = [clipping]; - } - var trivial = trivialOperation(subject, clipping, operation); - if (trivial) { - return trivial === EMPTY ? null : trivial; - } - var sbbox = [Infinity, Infinity, -Infinity, -Infinity]; - var cbbox = [Infinity, Infinity, -Infinity, -Infinity]; - - // console.time('fill queue'); - var eventQueue = fillQueue(subject, clipping, sbbox, cbbox, operation); - //console.timeEnd('fill queue'); - - trivial = compareBBoxes(subject, clipping, sbbox, cbbox, operation); - if (trivial) { - return trivial === EMPTY ? null : trivial; - } - // console.time('subdivide edges'); - var sortedEvents = subdivide(eventQueue, subject, clipping, sbbox, cbbox, operation); - //console.timeEnd('subdivide edges'); - - // console.time('connect vertices'); - var contours = connectEdges(sortedEvents); - //console.timeEnd('connect vertices'); - - // Convert contours to polygons - var polygons = []; - for (var i = 0; i < contours.length; i++) { - var contour = contours[i]; - if (contour.isExterior()) { - // The exterior ring goes first - var rings = [contour.points]; - // Followed by holes if any - for (var j = 0; j < contour.holeIds.length; j++) { - var holeId = contour.holeIds[j]; - rings.push(contours[holeId].points); - } - polygons.push(rings); - } - } - - return polygons; - } - - function union (subject, clipping) { - return boolean(subject, clipping, UNION); - } - - function diff (subject, clipping) { - return boolean(subject, clipping, DIFFERENCE); - } - - function xor (subject, clipping) { - return boolean(subject, clipping, XOR); - } - - function intersection$1 (subject, clipping) { - return boolean(subject, clipping, INTERSECTION); - } - - // import * as martinez from '../../dist/martinez.min'; - - var mode = window.location.hash.substring(1); - var path = '../test/fixtures/'; - var file; - - switch (mode) { - case 'geo': - file = 'asia.geojson'; - break; - case 'states': - file = 'states_source.geojson'; - break; - case 'trapezoid': - file = 'trapezoid-box.geojson'; - break; - case 'canada': - file = 'canada.geojson'; - break; - case 'horseshoe': - file = 'horseshoe.geojson'; - break; - case 'hourglasses': - file = 'hourglasses.geojson'; - break; - case 'edge_overlap': - file = 'polygon_trapezoid_edge_overlap.geojson'; - break; - case 'touching_boxes': - file = 'touching_boxes.geojson'; - break; - case 'triangles': - file = 'two_pointed_triangles.geojson'; - break; - case 'holecut': - file = 'hole_cut.geojson'; - break; - case 'overlapping_segments': - file = 'overlapping_segments.geojson'; - break; - case 'overlap_loop': - file = 'overlap_loop.geojson'; - break; - case 'overlap_y': - file = 'overlap_y.geojson'; - break; - case 'overlap_two': - file = 'overlap_two.geojson'; - break; - case 'disjoint_boxes': - file = 'disjoint_boxes.geojson'; - break; - case 'polygons_edge_overlap': - file = 'polygons_edge_overlap.geojson'; - break; - case 'vertical_boxes': - file = 'vertical_boxes.geojson'; - break; - case 'collapsed': - file = 'collapsed.geojson'; - break; - case 'fatal1': - file = 'fatal1.geojson'; - break; - case 'fatal2': - file = 'fatal2.geojson'; - break; - case 'fatal3': - file = 'fatal3.geojson'; - break; - case 'fatal4': - file = 'fatal4.geojson'; - break; - case 'rectangles': - file = 'rectangles.geojson'; - break; - default: - file = 'hole_hole.geojson'; - break; - } - - console.log(mode); - - - var OPERATIONS = { - INTERSECTION: 0, - UNION: 1, - DIFFERENCE: 2, - XOR: 3 - }; - - var div = document.createElement('div'); - div.id = 'image-map'; - div.style.width = div.style.height = '100%'; - document.body.appendChild(div); - - // create the slippy map - var map = window.map = L.map('image-map', { - minZoom: 1, - maxZoom: 20, - center: [0, 0], - zoom: 2, - crs: mode === 'geo' ? L.CRS.EPSG4326 : L.extend({}, L.CRS.Simple, { - transformation: new L.Transformation(1/8, 0, -1/8, 0) - }), - editable: true - }); - - map.addControl(new L.NewPolygonControl({ - callback: map.editTools.startPolygon - })); - map.addControl(new L.Coordinates()); - map.addControl(new L.BooleanControl({ - callback: run, - clear: clear - })); - - var drawnItems = window.drawnItems = L.geoJson().addTo(map); - var rawData = null; - function loadData(path) { - console.log(path); - fetch(path) - .then(function (r) { return r.json(); }) - .then(function (json) { - drawnItems.addData(json); - rawData = json; - map.fitBounds(drawnItems.getBounds().pad(0.05), { animate: false }); - }); - } - - function clear() { - drawnItems.clearLayers(); - results.clearLayers(); - rawData = null; - } - - var reader = new jsts.io.GeoJSONReader(); - var writer = new jsts.io.GeoJSONWriter(); - - function getClippingPoly (layers) { - if (rawData !== null && rawData.features.length > 1) { return rawData.features[1]; } - return layers[1].toGeoJSON(); - } - - function run (op) { - var layers = drawnItems.getLayers(); - if (layers.length < 2) { return; } - var subject = rawData !== null ? rawData.features[0] : layers[0].toGeoJSON(); - var clipping = getClippingPoly(layers); - - //console.log('input', subject, clipping, op); - - // subject = JSON.parse(JSON.stringify(subject)); - // clipping = JSON.parse(JSON.stringify(clipping)); - - var operation; - if (op === OPERATIONS.INTERSECTION) { - operation = intersection$1; - } else if (op === OPERATIONS.UNION) { - operation = union; - } else if (op === OPERATIONS.DIFFERENCE) { - operation = diff; - } else if (op === 5) { // B - A - operation = diff; - - var temp = subject; - subject = clipping; - clipping = temp; - } else { - operation = xor; - } - - console.time('martinez'); - var result = operation(subject.geometry.coordinates, clipping.geometry.coordinates); - console.timeEnd('martinez'); - - console.log('result', result); - // console.log(JSON.stringify(result)); - results.clearLayers(); - - if (result !== null) { - results.addData({ - 'type': 'Feature', - 'geometry': { - 'type': 'MultiPolygon', - 'coordinates': result - } - }); - - setTimeout(function() { - console.time('jsts'); - var s = reader.read(subject); - var c = reader.read(clipping); - var res; - if (op === OPERATIONS.INTERSECTION) { - res = s.geometry.intersection(c.geometry); - } else if (op === OPERATIONS.UNION) { - res = s.geometry.union(c.geometry); - } else if (op === OPERATIONS.DIFFERENCE) { - res = s.geometry.difference(c.geometry); - } else { - res = s.geometry.symDifference(c.geometry); - } - res = writer.write(res); - console.timeEnd('jsts'); - // console.log('JSTS result', res); - }, 500); - } - } - - map.on('editable:created', function(evt) { - drawnItems.addLayer(evt.layer); - evt.layer.on('click', function(e) { - if ((e.originalEvent.ctrlKey || e.originalEvent.metaKey) && this.editEnabled()) { - this.editor.newHole(e.latlng); - } - }); - }); - - var results = window.results = L.geoJson(null, { - style: function(feature) { - return { - color: 'red', - weight: 1 - }; - } - }).addTo(map); - - loadData(path + file); - -}(L)); diff --git a/demo/js/coordinates.js b/demo/js/coordinates.js deleted file mode 100644 index 2b4c367..0000000 --- a/demo/js/coordinates.js +++ /dev/null @@ -1,20 +0,0 @@ -import L from 'leaflet'; - -L.Coordinates = L.Control.extend({ - options: { - position: 'bottomright' - }, - - onAdd: function(map) { - this._container = L.DomUtil.create('div', 'leaflet-bar'); - this._container.style.background = '#ffffff'; - map.on('mousemove', this._onMouseMove, this); - return this._container; - }, - - _onMouseMove: function(e) { - this._container.innerHTML = '' + - e.latlng.lng.toFixed(3) + ', ' + e.latlng.lat.toFixed(3) + ''; - } - -}); diff --git a/demo/js/index.js b/demo/js/index.js deleted file mode 100644 index 4af1f22..0000000 --- a/demo/js/index.js +++ /dev/null @@ -1,240 +0,0 @@ -import './coordinates'; -import './polygoncontrol'; -import './booleanopcontrol'; -import * as martinez from '../../index'; -// import * as martinez from '../../dist/martinez.min'; - -let mode = window.location.hash.substring(1); -let path = '../test/fixtures/'; -const ext = '.geojson'; -let file; - -let files = [ - 'asia', 'trapezoid-box', 'canada', 'horseshoe', 'hourglasses', 'overlap_y', - 'polygon_trapezoid_edge_overlap', 'touching_boxes', 'two_pointed_triangles', - 'hole_cut', 'overlapping_segments', 'overlap_loop', 'disjoint_boxes' -]; - -switch (mode) { - case 'geo': - file = 'asia.geojson'; - break; - case 'states': - file = 'states_source.geojson'; - break; - case 'trapezoid': - file = 'trapezoid-box.geojson'; - break; - case 'canada': - file = 'canada.geojson'; - break; - case 'horseshoe': - file = 'horseshoe.geojson'; - break; - case 'hourglasses': - file = 'hourglasses.geojson'; - break; - case 'edge_overlap': - file = 'polygon_trapezoid_edge_overlap.geojson'; - break; - case 'touching_boxes': - file = 'touching_boxes.geojson'; - break; - case 'triangles': - file = 'two_pointed_triangles.geojson'; - break; - case 'holecut': - file = 'hole_cut.geojson'; - break; - case 'overlapping_segments': - file = 'overlapping_segments.geojson'; - break; - case 'overlap_loop': - file = 'overlap_loop.geojson'; - break; - case 'overlap_y': - file = 'overlap_y.geojson'; - break; - case 'overlap_two': - file = 'overlap_two.geojson'; - break; - case 'disjoint_boxes': - file = 'disjoint_boxes.geojson'; - break; - case 'polygons_edge_overlap': - file = 'polygons_edge_overlap.geojson'; - break; - case 'vertical_boxes': - file = 'vertical_boxes.geojson'; - break; - case 'collapsed': - file = 'collapsed.geojson'; - break; - case 'fatal1': - file = 'fatal1.geojson'; - break; - case 'fatal2': - file = 'fatal2.geojson'; - break; - case 'fatal3': - file = 'fatal3.geojson'; - break; - case 'fatal4': - file = 'fatal4.geojson'; - break; - case 'rectangles': - file = 'rectangles.geojson'; - break; - default: - file = 'hole_hole.geojson'; - break; -} - -console.log(mode); - - -var OPERATIONS = { - INTERSECTION: 0, - UNION: 1, - DIFFERENCE: 2, - XOR: 3 -}; - -var div = document.createElement('div'); -div.id = 'image-map'; -div.style.width = div.style.height = '100%'; -document.body.appendChild(div); - -// create the slippy map -var map = window.map = L.map('image-map', { - minZoom: 1, - maxZoom: 20, - center: [0, 0], - zoom: 2, - crs: mode === 'geo' ? L.CRS.EPSG4326 : L.extend({}, L.CRS.Simple, { - transformation: new L.Transformation(1/8, 0, -1/8, 0) - }), - editable: true -}); - -map.addControl(new L.NewPolygonControl({ - callback: map.editTools.startPolygon -})); -map.addControl(new L.Coordinates()); -map.addControl(new L.BooleanControl({ - callback: run, - clear: clear -})); - -var drawnItems = window.drawnItems = L.geoJson().addTo(map); -var rawData = null; -function loadData(path) { - console.log(path); - fetch(path) - .then((r) => r.json()) - .then((json) => { - drawnItems.addData(json); - rawData = json; - map.fitBounds(drawnItems.getBounds().pad(0.05), { animate: false }); - }); -} - -function clear() { - drawnItems.clearLayers(); - results.clearLayers(); - rawData = null; -} - -var reader = new jsts.io.GeoJSONReader(); -var writer = new jsts.io.GeoJSONWriter(); - -function getClippingPoly (layers) { - if (rawData !== null && rawData.features.length > 1) return rawData.features[1]; - return layers[1].toGeoJSON(); -} - -function run (op) { - var layers = drawnItems.getLayers(); - if (layers.length < 2) return; - var subject = rawData !== null ? rawData.features[0] : layers[0].toGeoJSON(); - var clipping = getClippingPoly(layers); - - //console.log('input', subject, clipping, op); - - // subject = JSON.parse(JSON.stringify(subject)); - // clipping = JSON.parse(JSON.stringify(clipping)); - - var operation; - if (op === OPERATIONS.INTERSECTION) { - operation = martinez.intersection; - } else if (op === OPERATIONS.UNION) { - operation = martinez.union; - } else if (op === OPERATIONS.DIFFERENCE) { - operation = martinez.diff; - } else if (op === 5) { // B - A - operation = martinez.diff; - - var temp = subject; - subject = clipping; - clipping = temp; - } else { - operation = martinez.xor; - } - - console.time('martinez'); - var result = operation(subject.geometry.coordinates, clipping.geometry.coordinates); - console.timeEnd('martinez'); - - console.log('result', result); - // console.log(JSON.stringify(result)); - results.clearLayers(); - - if (result !== null) { - results.addData({ - 'type': 'Feature', - 'geometry': { - 'type': 'MultiPolygon', - 'coordinates': result - } - }); - - setTimeout(function() { - console.time('jsts'); - var s = reader.read(subject); - var c = reader.read(clipping); - var res; - if (op === OPERATIONS.INTERSECTION) { - res = s.geometry.intersection(c.geometry); - } else if (op === OPERATIONS.UNION) { - res = s.geometry.union(c.geometry); - } else if (op === OPERATIONS.DIFFERENCE) { - res = s.geometry.difference(c.geometry); - } else { - res = s.geometry.symDifference(c.geometry); - } - res = writer.write(res); - console.timeEnd('jsts'); - // console.log('JSTS result', res); - }, 500); - } -} - -map.on('editable:created', function(evt) { - drawnItems.addLayer(evt.layer); - evt.layer.on('click', function(e) { - if ((e.originalEvent.ctrlKey || e.originalEvent.metaKey) && this.editEnabled()) { - this.editor.newHole(e.latlng); - } - }); -}); - -var results = window.results = L.geoJson(null, { - style: function(feature) { - return { - color: 'red', - weight: 1 - }; - } -}).addTo(map); - -loadData(path + file); diff --git a/demo/js/polygoncontrol.js b/demo/js/polygoncontrol.js deleted file mode 100644 index 70a2623..0000000 --- a/demo/js/polygoncontrol.js +++ /dev/null @@ -1,35 +0,0 @@ -import L from 'leaflet'; - -L.EditControl = L.Control.extend({ - - options: { - position: 'topleft', - callback: null, - kind: '', - html: '' - }, - - onAdd: function (map) { - var container = L.DomUtil.create('div', 'leaflet-control leaflet-bar'), - link = L.DomUtil.create('a', '', container); - - link.href = '#'; - link.title = 'Create a new ' + this.options.kind; - link.innerHTML = this.options.html; - L.DomEvent.on(link, 'click', L.DomEvent.stop) - .on(link, 'click', function () { - window.LAYER = this.options.callback.call(map.editTools); - }, this); - - return container; - } - -}); - -L.NewPolygonControl = L.EditControl.extend({ - options: { - position: 'topleft', - kind: 'polygon', - html: '▰' - } -}); diff --git a/demo/orthogonal.html b/demo/orthogonal.html index 14206be..726c638 100644 --- a/demo/orthogonal.html +++ b/demo/orthogonal.html @@ -1,15 +1,21 @@ - + - - + + Martinez Clipping - - - - + + + - + diff --git a/demo/polygoncontrol.ts b/demo/polygoncontrol.ts new file mode 100644 index 0000000..2eb1efe --- /dev/null +++ b/demo/polygoncontrol.ts @@ -0,0 +1,62 @@ +import L from "leaflet"; + +declare global { + interface Window { + LAYER: any; + } +} + +declare module "leaflet" { + interface EditControlOptions extends ControlOptions { + callback?: any; + kind?: string; + html?: string; + } + + namespace Control { + class EditControl extends Control { + constructor(options?: EditControlOptions); + options: EditControlOptions; + } + + class NewPolygonControl extends EditControl { + constructor(options?: EditControlOptions); + } + } +} + +(L.Control as any).EditControl = L.Control.extend({ + options: { + position: "topleft", + callback: null, + kind: "", + html: "", + }, + + onAdd: function (this: any, map: any) { + const container = L.DomUtil.create("div", "leaflet-control leaflet-bar"); + const link = L.DomUtil.create("a", "", container); + + link.href = "#"; + link.title = "Create a new " + this.options.kind; + link.innerHTML = this.options.html; + L.DomEvent.on(link, "click", L.DomEvent.stop).on( + link, + "click", + function (this: any) { + window.LAYER = this.options.callback.call(map.editTools); + }, + this + ); + + return container; + }, +}); + +(L as any).NewPolygonControl = (L.Control as any).EditControl.extend({ + options: { + position: "topleft", + kind: "polygon", + html: "▰", + }, +}); diff --git a/demo/styles.css b/demo/styles.css new file mode 100644 index 0000000..b38c48a --- /dev/null +++ b/demo/styles.css @@ -0,0 +1,18 @@ +html, +body, +#image-map { + width: 100%; + height: 100%; + margin: 0; + padding: 0; +} + +#diff-map, +#union-map, +#intersection-map { + display: none; + width: 400px; + height: 400px; + margin-right: 10px; + float: left; +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..e8bb5d9 --- /dev/null +++ b/index.html @@ -0,0 +1,15 @@ + + + + + Martinez Clipping - Development + + + +

Redirecting to demo...

+ Click here if not redirected + + \ No newline at end of file diff --git a/index.js b/index.ts similarity index 52% rename from index.js rename to index.ts index 04441cf..44dd2a4 100644 --- a/index.js +++ b/index.ts @@ -5,20 +5,21 @@ import { UNION, XOR } from './src/operation'; +import { Geometry } from './src/types'; -export function union (subject, clipping) { +export function union(subject: Geometry, clipping: Geometry): Geometry | null { return boolean(subject, clipping, UNION); } -export function diff (subject, clipping) { +export function diff(subject: Geometry, clipping: Geometry): Geometry | null { return boolean(subject, clipping, DIFFERENCE); } -export function xor (subject, clipping) { +export function xor(subject: Geometry, clipping: Geometry): Geometry | null { return boolean(subject, clipping, XOR); } -export function intersection (subject, clipping) { +export function intersection(subject: Geometry, clipping: Geometry): Geometry | null { return boolean(subject, clipping, INTERSECTION); } diff --git a/oxlint.json b/oxlint.json new file mode 100644 index 0000000..9e539ea --- /dev/null +++ b/oxlint.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxlint/configuration_schema.json", + "rules": { + "typescript": "warn", + "correctness": "error", + "suspicious": "warn", + "perf": "warn" + }, + "allow": [ + "no-unused-vars", + "prefer-const" + ] +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 14b6f58..ca2e016 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,2790 +1,3441 @@ { "name": "martinez-polygon-clipping", - "version": "0.7.4", - "lockfileVersion": 2, + "version": "0.8.0", + "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "martinez-polygon-clipping", - "version": "0.7.4", + "version": "0.8.0", "license": "MIT", "dependencies": { "robust-predicates": "^2.0.4", "splaytree": "^0.1.4", - "tinyqueue": "^1.2.0" + "tinyqueue": "3.0.0" }, "devDependencies": { "@turf/union": "^4.6.0", "@types/geojson": "^1.0.2", + "@types/glob": "^8.1.0", + "@types/jsts": "0.17.24", + "@types/leaflet": "1.9.21", + "@types/node": "^20.0.0", + "@vitest/ui": "^1.0.0", "benchmark": "^2.1.4", - "buble": "^0.19.3", - "eslint": "^6.8.0", - "eslint-plugin-import-order": "^2.1.4", - "eslint-plugin-jsdoc": "^20.0.2", - "eslint-plugin-promise": "^3.8.0", "geojson-project": "^1.0.0", - "http-server": "^0.12.1", + "gh-pages": "^6.1.1", + "glob": "^11.0.3", "json-stringify-pretty-compact": "^2.0.0", - "leaflet": "^1.2.0", - "leaflet-editable": "^1.1.0", - "load-json-file": "^2.0.0", - "npm-run-all": "^4.1.5", - "reify": "^0.20.12", - "rollup": "^1.28.0", - "rollup-plugin-buble": "^0.19.8", - "rollup-plugin-commonjs": "^10.1.0", - "rollup-plugin-node-resolve": "^5.2.0", - "tap-spec": "^5.0.0", - "tap-status": "^1.0.1", - "tape": "^4.12.1", - "typescript": "^3.7.4", - "uglify-js": "^3.3.21" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "leaflet": "1.9.4", + "leaflet-editable": "^1.3.2", + "oxlint": "^0.9.10", + "typescript": "^5.0.0", + "vite": "^5.0.0", + "vite-plugin-dts": "^3.0.0", + "vitest": "^1.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, - "dependencies": { - "@babel/highlight": "^7.18.6" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" }, "engines": { - "node": ">=6.9.0" + "node": ">=6.0.0" } }, - "node_modules/@turf/union": { - "version": "4.6.0", + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", "dev": true, "license": "MIT", "dependencies": { - "jsts": "1.3.0" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@types/estree": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", - "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", - "dev": true - }, - "node_modules/@types/geojson": { - "version": "1.0.6", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "17.0.45", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", + "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" + ], "dev": true, - "dependencies": { - "@types/node": "*" + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" } }, - "node_modules/acorn": { - "version": "8.7.1", + "node_modules/@esbuild/android-arm": { + "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" + ], "dev": true, "license": "MIT", - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=0.4.0" + "node": ">=12" } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", + "node_modules/@esbuild/android-arm64": { + "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" + ], "dev": true, "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "node_modules/@esbuild/darwin-arm64": { + "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" + ], "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "node_modules/@esbuild/darwin-x64": { + "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" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "node_modules/@esbuild/freebsd-arm64": { + "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" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/@esbuild/freebsd-x64": { + "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" + ], "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "node_modules/@esbuild/linux-arm64": { + "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" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/async": { - "version": "2.6.4", + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", - "dependencies": { - "lodash": "^4.17.14" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/balanced-match": { - "version": "1.0.2", + "node_modules/@esbuild/linux-loong64": { + "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" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/basic-auth": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", - "integrity": "sha512-CtGuTyWf3ig+sgRyC7uP6DM3N+5ur/p8L+FPfsd+BbIfIs74TFfCajZTHnCw6K5dqM0bZEbRIqRy1fAdiUJhTA==", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.6" + "node": ">=12" } }, - "node_modules/benchmark": { - "version": "2.1.4", + "node_modules/@esbuild/linux-ppc64": { + "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" + ], "dev": true, "license": "MIT", - "dependencies": { - "lodash": "^4.17.4", - "platform": "^1.3.3" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/brace-expansion": { - "version": "1.1.11", + "node_modules/@esbuild/linux-riscv64": { + "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" + ], "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/buble": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/buble/-/buble-0.19.8.tgz", - "integrity": "sha512-IoGZzrUTY5fKXVkgGHw3QeXFMUNBFv+9l8a4QJKG1JhG3nCMHTdEX1DCOg8568E2Q9qvAQIiSokv6Jsgx8p2cA==", + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], "dev": true, - "dependencies": { - "acorn": "^6.1.1", - "acorn-dynamic-import": "^4.0.0", - "acorn-jsx": "^5.0.1", - "chalk": "^2.4.2", - "magic-string": "^0.25.3", - "minimist": "^1.2.0", - "os-homedir": "^2.0.0", - "regexpu-core": "^4.5.4" - }, - "bin": { - "buble": "bin/buble" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/buble/node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "node_modules/@esbuild/linux-x64": { + "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" + ], "dev": true, - "bin": { - "acorn": "bin/acorn" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.4.0" + "node": ">=12" } }, - "node_modules/buble/node_modules/acorn-dynamic-import": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", - "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], "dev": true, - "peerDependencies": { - "acorn": "^6.0.0" + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" } }, - "node_modules/buffer-shims": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g==", - "dev": true - }, - "node_modules/builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/call-bind": { - "version": "1.0.2", + "node_modules/@esbuild/sunos-x64": { + "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" + ], "dev": true, "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/@esbuild/win32-ia32": { + "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" + ], "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "node_modules/@esbuild/win32-x64": { + "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" + ], "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 10" + "node": "20 || >=22" } }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", "dev": true, + "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" } }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, "engines": { - "node": ">=0.1.90" + "node": ">=12" } }, - "node_modules/comment-parser": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.7.6.tgz", - "integrity": "sha512-GKNxVA7/iuTnAqGADlTWX4tkhzxZKXp5fLJqKTlQLHkE65XDUKutZ3BHaJC5IGcper2tT3QRD1xr4o3jNpgXXg==", + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, "engines": { - "node": ">= 6.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/concat-map": { - "version": "0.0.1", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "node_modules/corser": { - "version": "2.0.1", + "node_modules/@microsoft/api-extractor": { + "version": "7.43.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.0.tgz", + "integrity": "sha512-GFhTcJpB+MI6FhvXEI9b2K0snulNLWHqC/BbcJtyNYcKUiw7l3Lgis5ApsYncJ0leALX7/of4XfmXk+maT111w==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "@microsoft/api-extractor-model": "7.28.13", + "@microsoft/tsdoc": "0.14.2", + "@microsoft/tsdoc-config": "~0.16.1", + "@rushstack/node-core-library": "4.0.2", + "@rushstack/rig-package": "0.5.2", + "@rushstack/terminal": "0.10.0", + "@rushstack/ts-command-line": "4.19.1", + "lodash": "~4.17.15", + "minimatch": "~3.0.3", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "source-map": "~0.6.1", + "typescript": "5.4.2" }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, "bin": { - "semver": "bin/semver" + "api-extractor": "bin/api-extractor" } }, - "node_modules/debug": { - "version": "4.3.4", + "node_modules/@microsoft/api-extractor-model": { + "version": "7.28.13", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.13.tgz", + "integrity": "sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==", "dev": true, "license": "MIT", "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "@microsoft/tsdoc": "0.14.2", + "@microsoft/tsdoc-config": "~0.16.1", + "@rushstack/node-core-library": "4.0.2" } }, - "node_modules/deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "node_modules/@microsoft/api-extractor/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" + "yallist": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=10" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/define-properties": { - "version": "1.1.4", + "node_modules/@microsoft/api-extractor/node_modules/minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "*" } }, - "node_modules/defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==", - "dev": true - }, - "node_modules/doctrine": { - "version": "3.0.0", + "node_modules/@microsoft/api-extractor/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "license": "Apache-2.0", + "license": "ISC", "dependencies": { - "esutils": "^2.0.2" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=6.0.0" + "node": ">=10" } }, - "node_modules/dotignore": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz", - "integrity": "sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==", + "node_modules/@microsoft/api-extractor/node_modules/typescript": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", "dev": true, - "dependencies": { - "minimatch": "^3.0.4" - }, + "license": "Apache-2.0", "bin": { - "ignored": "bin/ignored" - } - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true - }, - "node_modules/ecstatic": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-3.3.2.tgz", - "integrity": "sha512-fLf9l1hnwrHI2xn9mEDT7KIi22UDqA2jaCwyCbSUJh9a1V+LEUSL/JO/6TIz/QyuBURWUHrFL5Kg2TtO1bkkog==", - "deprecated": "This package is unmaintained and deprecated. See the GH Issue 259.", - "dev": true, - "dependencies": { - "he": "^1.1.1", - "mime": "^1.6.0", - "minimist": "^1.1.0", - "url-join": "^2.0.5" + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, - "bin": { - "ecstatic": "lib/ecstatic.js" + "engines": { + "node": ">=14.17" } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "node_modules/@microsoft/tsdoc": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", + "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", + "dev": true, + "license": "MIT" }, - "node_modules/error-ex": { - "version": "1.3.2", + "node_modules/@microsoft/tsdoc-config": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz", + "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==", "dev": true, "license": "MIT", "dependencies": { - "is-arrayish": "^0.2.1" + "@microsoft/tsdoc": "0.14.2", + "ajv": "~6.12.6", + "jju": "~1.4.0", + "resolve": "~1.19.0" } }, - "node_modules/es-abstract": { - "version": "1.20.1", + "node_modules/@microsoft/tsdoc-config/node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 8" } }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">= 8" } }, - "node_modules/eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.3", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">= 8" } }, - "node_modules/eslint-plugin-import-order": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import-order/-/eslint-plugin-import-order-2.1.4.tgz", - "integrity": "sha512-cHThJ45zFx5UtRZ+Jd6XO89bLriKkdckAHZoSxknlK3BELmAO6Gqe74A7j8rvL+1PEyNJF3Fsil/Rjwx8cqOow==", - "deprecated": "Use eslint-plugin-import instead (order rule)", + "node_modules/@oxlint/darwin-arm64": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@oxlint/darwin-arm64/-/darwin-arm64-0.9.10.tgz", + "integrity": "sha512-eOXKZYq5bnCSgDefgM5bzAg+4Fc//Rc4yjgKN8iDWUARweCaChiQXb6TXX8MfEfs6qayEMy6yVj0pqoFz0B1aw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oxlint/darwin-x64": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@oxlint/darwin-x64/-/darwin-x64-0.9.10.tgz", + "integrity": "sha512-UeYICDvLUaUOcY+0ugZUEmBMRLP+x8iTgL7TeY6BlpGw2ahbtUOTbyIIRWtr/0O++TnjZ+v8TzhJ9crw6Ij6dg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oxlint/linux-arm64-gnu": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-gnu/-/linux-arm64-gnu-0.9.10.tgz", + "integrity": "sha512-0Zn+vqHhrZyufFBfq9WOgiIool0gCR14BLsdS+0Dwd9o+kNxPGA5q7erQFkiC4rpkxtfBHeD3iIKMMt7d29Kyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/linux-arm64-musl": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-musl/-/linux-arm64-musl-0.9.10.tgz", + "integrity": "sha512-tkQcWpYwF42bA/uRaV2iMFePHkBjTTgomOgeEaiw6XOSJX4nBEqGIIboqqLBWT4JnKCf/L+IG3y/e1MflhKByw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/linux-x64-gnu": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-gnu/-/linux-x64-gnu-0.9.10.tgz", + "integrity": "sha512-JHbkMUnibqaSMBvLHyqTL5cWxcGW+jw+Ppt2baLISpvo34a6fBR+PI7v/A92sEDWe0W1rPhypzCwA8mKpkQ3DA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/linux-x64-musl": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-musl/-/linux-x64-musl-0.9.10.tgz", + "integrity": "sha512-aBBwN7bQzidwHwEXr7BAdVvMTLWstCy5gikerjLnGDeCSXX9r+o6+yUzTOqZvOo66E+XBgOJaVbY8rsL1MLE0g==", + "cpu": [ + "x64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/win32-arm64": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@oxlint/win32-arm64/-/win32-arm64-0.9.10.tgz", + "integrity": "sha512-LXDnk7vKHT3IY6G1jq0O7+XMhtcHOYuxLGIx4KP+4xS6vKgBY+Bsq4xV3AtmtKlvnXkP5FxHpfLmcEtm5AWysA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@oxlint/win32-x64": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@oxlint/win32-x64/-/win32-x64-0.9.10.tgz", + "integrity": "sha512-w5XRAV4bhgwenjjpGYZGglqzG9Wv/sI+cjQWJBQsvfDXsr2w4vOBXzt1j3/Z3EcSqf4KtkCa/IIuAhQyeShUbA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "dev": true, + "license": "MIT", "dependencies": { - "builtin-modules": "^1.1.1", - "lodash.cond": "^4.2.0", - "lodash.find": "^4.2.0" + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=14.0.0" }, "peerDependencies": { - "eslint": ">=2" + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, - "node_modules/eslint-plugin-jsdoc": { - "version": "20.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-20.4.0.tgz", - "integrity": "sha512-c/fnEpwWLFeQn+A7pb1qLOdyhovpqGCWCeUv1wtzFNL5G+xedl9wHUnXtp3b1sGHolVimi9DxKVTuhK/snXoOw==", + "node_modules/@rollup/pluginutils/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==", "dev": true, - "dependencies": { - "comment-parser": "^0.7.2", - "debug": "^4.1.1", - "jsdoctypeparser": "^6.1.0", - "lodash": "^4.17.15", - "object.entries-ponyfill": "^1.0.1", - "regextras": "^0.7.0", - "semver": "^6.3.0", - "spdx-expression-parse": "^3.0.0" - }, + "license": "MIT" + }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=12" }, - "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0" + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/eslint-plugin-promise": { - "version": "3.8.0", + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz", + "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==", + "cpu": [ + "arm" + ], "dev": true, - "license": "ISC", - "engines": { - "node": ">=4" - } + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz", + "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz", + "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz", + "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz", + "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz", + "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz", + "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz", + "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz", + "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz", + "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz", + "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz", + "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz", + "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz", + "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz", + "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz", + "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz", + "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz", + "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz", + "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz", + "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", + "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", + "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/@rushstack/node-core-library": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", + "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", "dev": true, + "license": "MIT", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "z-schema": "~5.0.2" }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-scope/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "node_modules/@rushstack/node-core-library/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, + "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=6" + "node": ">=6 <7 || >=8" } }, - "node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/@rushstack/node-core-library/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, - "engines": { - "node": ">=4" + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "node_modules/@rushstack/node-core-library/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=10" } }, - "node_modules/espree/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "node_modules/@rushstack/node-core-library/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { - "acorn": "bin/acorn" + "semver": "bin/semver.js" }, "engines": { - "node": ">=0.4.0" + "node": ">=10" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/@rushstack/node-core-library/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">= 4.0.0" } }, - "node_modules/esquery": { - "version": "1.4.0", + "node_modules/@rushstack/rig-package": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.2.tgz", + "integrity": "sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" + "resolve": "~1.22.1", + "strip-json-comments": "~3.1.1" } }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/@rushstack/terminal": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.0.tgz", + "integrity": "sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==", "dev": true, + "license": "MIT", "dependencies": { - "estraverse": "^5.2.0" + "@rushstack/node-core-library": "4.0.2", + "supports-color": "~8.1.1" }, - "engines": { - "node": ">=4.0" + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/estraverse": { - "version": "5.3.0", + "node_modules/@rushstack/ts-command-line": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.1.tgz", + "integrity": "sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" + "license": "MIT", + "dependencies": { + "@rushstack/terminal": "0.10.0", + "@types/argparse": "1.0.38", + "argparse": "~1.0.9", + "string-argv": "~0.3.1" } }, - "node_modules/estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" }, - "node_modules/esutils": { - "version": "2.0.3", + "node_modules/@turf/union": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/@turf/union/-/union-4.7.3.tgz", + "integrity": "sha512-6mF3CJKJXGEUa9lNNM3yWc1dqEjEsoB92UoJPa0yr8zQOhgd4va1MoLh9QXHnWsGlevRa74Ob1e12mZxffcfdA==", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" + "license": "MIT", + "dependencies": { + "jsts": "1.3.0" } }, - "node_modules/eventemitter3": { - "version": "4.0.7", + "node_modules/@types/argparse": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", + "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", "dev": true, "license": "MIT" }, - "node_modules/events-to-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz", - "integrity": "sha512-inRWzRY7nG+aXZxBzEqYKB3HPgwflZRopAjDCHv0whhRx+MTUr1ei0ICZUypdyE0HRm4L2d5VEcIqLD6yl+BFA==", - "dev": true + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "node_modules/@types/geojson": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-1.0.6.tgz", + "integrity": "sha512-Xqg/lIZMrUd0VRmSRbCAewtwGZiAk3mEUDvV4op1tGl+LvyPcb/MIOSxTl9z+9+J+R4/vpjiCAT4xeKzH9ji1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", "dev": true, + "license": "MIT", "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" + "@types/minimatch": "^5.1.2", + "@types/node": "*" } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "node_modules/@types/jsts": { + "version": "0.17.24", + "resolved": "https://registry.npmjs.org/@types/jsts/-/jsts-0.17.24.tgz", + "integrity": "sha512-zZAAiAh7SjXCo5lYCMquz/klQVS9LVdSkAVXPk2BP/2l7FHqmfAFTj9PEld9zUFzXC/bgr04yiEDbDKDSaX7Hg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/openlayers": "*" + } + }, + "node_modules/@types/leaflet": { + "version": "1.9.21", + "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.21.tgz", + "integrity": "sha512-TbAd9DaPGSnzp6QvtYngntMZgcRk+igFELwR2N99XZn7RXUdKgsXMR+28bUO0rPsWp8MIu/f47luLIQuSLYv/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "license": "MIT" }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "node_modules/@types/node": { + "version": "20.19.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz", + "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/openlayers": { + "version": "4.6.23", + "resolved": "https://registry.npmjs.org/@types/openlayers/-/openlayers-4.6.23.tgz", + "integrity": "sha512-7jCPIa4D4LV03Rttae1AEqvkIN0+nc6Snz4IgA/IjsJD5O3ONxpscqIOdp1qAGuAsikR/ZC9vrPF9np8JRc6ig==", + "dev": true, + "license": "MIT" }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "node_modules/@vitest/expect": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.1.tgz", + "integrity": "sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==", "dev": true, + "license": "MIT", "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" + "@vitest/spy": "1.6.1", + "@vitest/utils": "1.6.1", + "chai": "^4.3.10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/vitest" } }, - "node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "node_modules/@vitest/runner": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.1.tgz", + "integrity": "sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==", "dev": true, + "license": "MIT", "dependencies": { - "flat-cache": "^2.0.1" + "@vitest/utils": "1.6.1", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "node_modules/@vitest/runner/node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", "dev": true, + "license": "MIT", "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "yocto-queue": "^1.0.0" }, "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.15.1", + "node_modules/@vitest/snapshot": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.1.tgz", + "integrity": "sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], "license": "MIT", - "engines": { - "node": ">=4.0" + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "node_modules/@vitest/spy": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.1.tgz", + "integrity": "sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==", "dev": true, + "license": "MIT", "dependencies": { - "is-callable": "^1.1.3" + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/function-bind": { - "version": "1.1.1", + "node_modules/@vitest/ui": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-1.6.1.tgz", + "integrity": "sha512-xa57bCPGuzEFqGjPs3vVLyqareG8DX0uMkr5U/v5vLv5/ZUrBrPL7gzxzTJedEyZxFMfsozwTIbbYfEQVo3kgg==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@vitest/utils": "1.6.1", + "fast-glob": "^3.3.2", + "fflate": "^0.8.1", + "flatted": "^3.2.9", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "sirv": "^2.0.4" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "1.6.1" + } }, - "node_modules/function.prototype.name": { - "version": "1.1.5", + "node_modules/@vitest/utils": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.1.tgz", + "integrity": "sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/vitest" } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", + "node_modules/@volar/language-core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.11.1.tgz", + "integrity": "sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@volar/source-map": "1.11.1" + } }, - "node_modules/functions-have-names": { - "version": "1.2.3", + "node_modules/@volar/source-map": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.11.1.tgz", + "integrity": "sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==", "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "dependencies": { + "muggle-string": "^0.3.1" } }, - "node_modules/geojson-project": { - "version": "1.0.1", + "node_modules/@volar/typescript": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.11.1.tgz", + "integrity": "sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@volar/language-core": "1.11.1", + "path-browserify": "^1.0.1" + } }, - "node_modules/get-intrinsic": { - "version": "1.1.2", + "node_modules/@vue/compiler-core": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.25.tgz", + "integrity": "sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==", "dev": true, "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/parser": "^7.28.5", + "@vue/shared": "3.5.25", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" } }, - "node_modules/get-symbol-description": { - "version": "1.0.0", + "node_modules/@vue/compiler-core/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.25.tgz", + "integrity": "sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@vue/compiler-core": "3.5.25", + "@vue/shared": "3.5.25" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/@vue/language-core": { + "version": "1.8.27", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.27.tgz", + "integrity": "sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==", "dev": true, + "license": "MIT", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "@volar/language-core": "~1.11.1", + "@volar/source-map": "~1.11.1", + "@vue/compiler-dom": "^3.3.0", + "@vue/shared": "^3.3.0", + "computeds": "^0.0.1", + "minimatch": "^9.0.3", + "muggle-string": "^0.3.1", + "path-browserify": "^1.0.1", + "vue-template-compiler": "^2.7.14" }, - "engines": { - "node": "*" + "peerDependencies": { + "typescript": "*" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/@vue/language-core/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, + "license": "MIT", "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" + "balanced-match": "^1.0.0" } }, - "node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "node_modules/@vue/language-core/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { - "type-fest": "^0.8.1" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/graceful-fs": { - "version": "4.2.10", + "node_modules/@vue/shared": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.25.tgz", + "integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==", "dev": true, - "license": "ISC" + "license": "MIT" }, - "node_modules/has": { - "version": "1.0.3", + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1" + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">= 0.4.0" + "node": ">=0.4.0" } }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-regex": "^2.0.0" + "acorn": "^8.11.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=0.4.0" } }, - "node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "engines": { - "node": ">=0.10.0" + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/has-bigints": { - "version": "1.0.2", + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", + "engines": { + "node": ">=12" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "sprintf-js": "~1.0.2" } }, - "node_modules/has-symbols": { - "version": "1.0.3", + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/has-tostringtag": { - "version": "1.0.0", + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.2" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "*" } }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "dev": true, - "bin": { - "he": "bin/he" - } + "license": "MIT" }, - "node_modules/hosted-git-info": { - "version": "2.8.9", + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, - "license": "ISC" + "license": "MIT" }, - "node_modules/http-proxy": { - "version": "1.18.1", + "node_modules/benchmark": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", + "integrity": "sha512-l9MlfN4M1K/H2fbhfMy3B7vJd6AGKJVQn2h6Sg/Yx+KckoUA7ewS5Vv6TjSq18ooE1kS9hhAlQRH3AkXIh/aOQ==", "dev": true, "license": "MIT", "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" + "lodash": "^4.17.4", + "platform": "^1.3.3" } }, - "node_modules/http-server": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.12.3.tgz", - "integrity": "sha512-be0dKG6pni92bRjq0kvExtj/NrrAd28/8fCXkaI/4piTwQMSDSLMhWyW0NI1V+DBI3aa1HMlQu46/HjVLfmugA==", + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { - "basic-auth": "^1.0.3", - "colors": "^1.4.0", - "corser": "^2.0.1", - "ecstatic": "^3.3.2", - "http-proxy": "^1.18.0", - "minimist": "^1.2.5", - "opener": "^1.5.1", - "portfinder": "^1.0.25", - "secure-compare": "3.0.1", - "union": "~0.5.0" - }, - "bin": { - "hs": "bin/http-server", - "http-server": "bin/http-server" - }, - "engines": { - "node": ">=6" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "fill-range": "^7.1.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 4" + "node": ">=8" } }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, + "license": "MIT", "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, "engines": { - "node": ">=0.8.19" + "node": "*" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" }, - "node_modules/inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", + "node_modules/commander": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, + "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": ">=18" } }, - "node_modules/inquirer/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/computeds": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz", + "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==", "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } + "license": "MIT" }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } + "license": "MIT" }, - "node_modules/inquirer/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=7.0.0" + "node": ">= 8" } }, - "node_modules/inquirer/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/inquirer/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", "dev": true, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/inquirer/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "ms": "^2.1.3" }, "engines": { - "node": ">=8" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "type-detect": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/internal-slot": { - "version": "1.0.3", + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, "engines": { - "node": ">= 0.4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "path-type": "^4.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true, "license": "MIT" }, - "node_modules/is-bigint": { - "version": "1.0.4", + "node_modules/email-addresses": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", + "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", "dev": true, - "license": "MIT", - "dependencies": { - "has-bigints": "^1.0.1" + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "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==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, + "hasInstallScript": true, "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "bin": { + "esbuild": "bin/esbuild" }, "engines": { - "node": ">= 0.4" + "node": ">=12" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optionalDependencies": { + "@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/is-callable": { - "version": "1.2.4", + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.8.0" } }, - "node_modules/is-core-module": { - "version": "2.9.0", + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "license": "MIT", "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@types/estree": "^1.0.0" } }, - "node_modules/is-date-object": { - "version": "1.0.5", + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=16.17" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/is-extglob": { - "version": "2.1.1", + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, - "node_modules/is-finite": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, - "engines": { - "node": ">=0.10.0" + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=8.6.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/is-glob": { - "version": "4.0.3", + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" + "reusify": "^1.0.4" } }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "dev": true, + "license": "MIT" }, - "node_modules/is-negative-zero": { - "version": "2.0.2", + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, - "node_modules/is-number-object": { - "version": "1.0.7", + "node_modules/filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { - "@types/estree": "*" + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/is-regex": { - "version": "1.1.4", + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8" } }, - "node_modules/is-string": { - "version": "1.0.7", + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true, - "license": "MIT", + "license": "ISC" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", "dependencies": { - "has-tostringtag": "^1.0.0" + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/is-symbol": { - "version": "1.0.4", + "node_modules/fs-extra": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", + "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", "dev": true, "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=14.14" } }, - "node_modules/is-weakref": { - "version": "1.0.2", + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2" - }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/geojson-project": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/geojson-project/-/geojson-project-1.0.1.tgz", + "integrity": "sha512-9x+VIogg1QQotqPUgg6EQqAnj6EANZQTAh/kKXsPO4WcaM4TukrAf6PnwNggkOUm5oAduoQTG1YiQOxY+6XAIw==", "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } + "license": "MIT" }, - "node_modules/jsdoctypeparser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-6.1.0.tgz", - "integrity": "sha512-UCQBZ3xCUBv/PLfwKAJhp6jmGOSLFNKzrotXGNgbKhWvz27wPsCsVeP7gIcHPElQw2agBmynAitXqhxR58XAmA==", + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, - "bin": { - "jsdoctypeparser": "bin/jsdoctypeparser" - }, + "license": "MIT", "engines": { - "node": ">=6" + "node": "*" } }, - "node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, - "bin": { - "jsesc": "bin/jsesc" + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stringify-pretty-compact": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/jsts": { - "version": "1.3.0", + "node_modules/gh-pages": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.3.0.tgz", + "integrity": "sha512-Ot5lU6jK0Eb+sszG8pciXdjMXdBJ5wODvgjR+imihTqsUWF2K6dJ9HST55lgqcs8wWcw6o6wAsUzfcYRhJPXbA==", "dev": true, - "license": "(EDL-1.0 OR EPL-1.0)", + "license": "MIT", + "dependencies": { + "async": "^3.2.4", + "commander": "^13.0.0", + "email-addresses": "^5.0.0", + "filenamify": "^4.3.0", + "find-cache-dir": "^3.3.1", + "fs-extra": "^11.1.1", + "globby": "^11.1.0" + }, + "bin": { + "gh-pages": "bin/gh-pages.js", + "gh-pages-clean": "bin/gh-pages-clean.js" + }, "engines": { - "node": ">= 4" + "node": ">=10" } }, - "node_modules/leaflet": { - "version": "1.8.0", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/leaflet-editable": { - "version": "1.2.0", - "dev": true, - "license": "WTFPL" - }, - "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "node_modules/glob": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">= 0.8.0" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/load-json-file": { - "version": "2.0.0", + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=4" + "node": ">= 6" } }, - "node_modules/lodash": { - "version": "4.17.21", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.cond": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", - "integrity": "sha512-RWjUhzGbzG/KfDwk+onqdXvrsNv47G9UCMJgSKalPTSqJQyxZhQophG9jgqLf+15TIbZ5a/yG2YKOWsH3dVy9A==", - "dev": true - }, - "node_modules/lodash.find": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz", - "integrity": "sha512-yaRZoAV3Xq28F1iafWN1+a0rflOej93l1DQUejs3SZ41h2O9UJBoS9aueGjPDgAl4B6tPC0NuuchLKaDQQ3Isg==", - "dev": true - }, - "node_modules/magic-string": { - "version": "0.25.9", + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "license": "MIT", "dependencies": { - "sourcemap-codec": "^1.4.8" - } - }, - "node_modules/memorystream": { - "version": "0.3.1", - "dev": true, + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, "engines": { - "node": ">= 0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } + "license": "ISC" }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/minimatch": { - "version": "3.1.2", + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "function-bind": "^1.1.2" }, "engines": { - "node": "*" + "node": ">= 0.4" } }, - "node_modules/minimist": { - "version": "1.2.6", - "dev": true, - "license": "MIT" - }, - "node_modules/mkdirp": { - "version": "0.5.6", + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" - }, "bin": { - "mkdirp": "bin/cmd.js" + "he": "bin/he" } }, - "node_modules/ms": { - "version": "2.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/nice-try": { - "version": "1.0.5", + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, - "license": "MIT" + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } }, - "node_modules/normalize-package-data": { - "version": "2.5.0", + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "license": "MIT", + "engines": { + "node": ">= 4" } }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "node_modules/npm-run-all": { - "version": "4.1.5", + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "memorystream": "^0.3.1", - "minimatch": "^3.0.4", - "pidtree": "^0.3.0", - "read-pkg": "^3.0.0", - "shell-quote": "^1.6.1", - "string.prototype.padend": "^3.0.0" - }, - "bin": { - "npm-run-all": "bin/npm-run-all/index.js", - "run-p": "bin/run-p/index.js", - "run-s": "bin/run-s/index.js" + "hasown": "^2.0.2" }, "engines": { - "node": ">= 4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/object-inspect": { - "version": "1.12.2", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8" } }, - "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/object-keys": { - "version": "1.1.1", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=0.12.0" } }, - "node_modules/object.assign": { - "version": "4.1.2", + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, "engines": { - "node": ">= 0.4" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/object.entries-ponyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.entries-ponyfill/-/object.entries-ponyfill-1.0.1.tgz", - "integrity": "sha512-j0ixssXc5GirDWhB2cLVPsOs9jx61G/iRndyMdToTsjMYY8BQmG1Ke6mwqXmpDiP8icye1YCR94NswNaa/yyzA==", - "dev": true - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, - "dependencies": { - "wrappy": "1" - } + "license": "ISC" }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "node_modules/jackspeak": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "mimic-fn": "^2.1.0" + "@isaacs/cliui": "^8.0.2" }, "engines": { - "node": ">=6" + "node": "20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/opener": { - "version": "1.5.2", + "node_modules/jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", "dev": true, - "license": "(WTFPL OR MIT)", - "bin": { - "opener": "bin/opener-bin.js" - } + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-pretty-compact": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-2.0.0.tgz", + "integrity": "sha512-WRitRfs6BGq4q8gTgOy4ek7iPFXjbra0H3PmDLKm2xnZ+Gh1HUhiKGgCZkSPNULlP7mvfu6FV/mOLhCarspADQ==", + "dev": true, + "license": "MIT" }, - "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "dev": true, + "license": "MIT", "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "universalify": "^2.0.0" }, - "engines": { - "node": ">= 0.8.0" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/os-homedir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-2.0.0.tgz", - "integrity": "sha512-saRNz0DSC5C/I++gFIaJTXoFJMRwiP5zHar5vV3xQ2TkgEw6hDCcU5F272JjUylpiVgBrZNQHnfjkLabTfb92Q==", - "deprecated": "This is not needed anymore. Use `require('os').homedir()` instead.", + "node_modules/jsts": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsts/-/jsts-1.3.0.tgz", + "integrity": "sha512-uFcaiZ5ba3Y6lfHNFikk64Kdkfx01iq3GE+K2S2k95uDcJcKxMusMd2RGgYWeS8EeUVX6eadOqwEzwA8yyGOaQ==", "dev": true, + "license": "(EDL-1.0 OR EPL-1.0)", "engines": { - "node": ">=0.10.0" + "node": ">= 4" } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", "dev": true, - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "node_modules/leaflet": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/leaflet-editable": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/leaflet-editable/-/leaflet-editable-1.3.2.tgz", + "integrity": "sha512-iDTXR0byKWRiPliNrQrmZtbHHrr/ONZwoFoIzUHP2MQJQwgqzeblc1OKrT0ryOEzf0PFtrClk9SksAbeQpsmXw==", "dev": true, + "license": "WTFPL" + }, + "node_modules/local-pkg": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz", + "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==", + "dev": true, + "license": "MIT", "dependencies": { - "callsites": "^3.0.0" + "mlly": "^1.7.3", + "pkg-types": "^1.2.1" }, "engines": { - "node": ">=6" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/parse-json": { - "version": "2.2.0", + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "license": "MIT", "dependencies": { - "error-ex": "^1.2.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/parse-ms": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz", - "integrity": "sha512-LpH1Cf5EYuVjkBvCDBYvkUPh+iv2bk3FHflxHkpCYT0/FZ1d3N3uJaLiHr4yGuMcFUhv6eAivitTvWZI4B/chg==", + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true, - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } + "license": "MIT" }, - "node_modules/path-parse": { - "version": "1.0.7", + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", "dev": true, "license": "MIT" }, - "node_modules/path-type": { - "version": "3.0.0", + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, "license": "MIT", "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" + "get-func-name": "^2.0.1" } }, - "node_modules/path-type/node_modules/pify": { - "version": "3.0.0", + "node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=4" + "node": "20 || >=22" } }, - "node_modules/pidtree": { - "version": "0.3.1", + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, "license": "MIT", - "bin": { - "pidtree": "bin/pidtree.js" - }, - "engines": { - "node": ">=0.10" + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/pify": { - "version": "2.3.0", + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/platform": { - "version": "1.3.6", + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true, "license": "MIT" }, - "node_modules/plur": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz", - "integrity": "sha512-qSnKBSZeDY8ApxwhfVIwKwF36KVJqb1/9nzYYq3j3vdwocULCXT8f8fQGkiw1Nk9BGfxiDagEe/pwakA+bOBqw==", + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 8" } }, - "node_modules/portfinder": { - "version": "1.0.28", + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" + "braces": "^3.0.3", + "picomatch": "^2.3.1" }, "engines": { - "node": ">= 0.12.0" + "node": ">=8.6" } }, - "node_modules/portfinder/node_modules/debug": { - "version": "3.2.7", + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/pretty-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz", - "integrity": "sha512-H2enpsxzDhuzRl3zeSQpQMirn8dB0Z/gxW96j06tMfTviUWvX14gjKb7qd1gtkUyYhDPuoNe00K5PqNvy2oQNg==", - "dev": true, - "dependencies": { - "is-finite": "^1.0.1", - "parse-ms": "^1.0.0", - "plur": "^1.0.0" + "node": ">=12" }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==", - "dev": true - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/qs": { - "version": "6.11.0", + "node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", "dev": true, - "license": "BSD-3-Clause", + "license": "BlueOak-1.0.0", "dependencies": { - "side-channel": "^1.0.4" + "@isaacs/brace-expansion": "^5.0.0" }, "engines": { - "node": ">=0.6" + "node": "20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/re-emitter": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/re-emitter/-/re-emitter-1.1.3.tgz", - "integrity": "sha512-bHJul9CWcocrS+w5e5QrKYXV9NkbSA9hxSEyhYuctwm6keY9NXR2Xt/4A0vbMP0QvuwyfEyb4bkowYXv1ziEbg==", - "dev": true - }, - "node_modules/read-pkg": { - "version": "3.0.0", + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, - "license": "MIT", - "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, + "license": "ISC", "engines": { - "node": ">=4" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/read-pkg/node_modules/load-json-file": { - "version": "4.0.0", + "node_modules/mlly": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", + "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", "dev": true, "license": "MIT", "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" + "acorn": "^8.15.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.1" } }, - "node_modules/read-pkg/node_modules/parse-json": { - "version": "4.0.0", + "node_modules/mlly/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true, - "license": "MIT", - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } + "license": "MIT" }, - "node_modules/read-pkg/node_modules/pify": { - "version": "3.0.0", + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=10" } }, - "node_modules/readable-stream": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", - "integrity": "sha512-iuxqX7b7FYt08AriYECxUsK9KTXE3A/FenxIa3IPmvANHxaTP/wGIwwf+IidvvIDk/MsCp/oEV6A8CXo4SDcCg==", + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/muggle-string": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.3.1.tgz", + "integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==", "dev": true, - "dependencies": { - "buffer-shims": "~1.0.0", - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~1.0.0", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "node_modules/regenerate-unicode-properties": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", - "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, - "dependencies": { - "regenerate": "^1.4.2" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": ">=4" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/regexp.prototype.flags": { - "version": "1.4.3", + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" + "path-key": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=6.5.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/regexpu-core": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", - "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, + "license": "MIT", "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^9.0.0", - "regjsgen": "^0.5.2", - "regjsparser": "^0.7.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" + "mimic-fn": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/regextras": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.7.1.tgz", - "integrity": "sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w==", + "node_modules/oxlint": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-0.9.10.tgz", + "integrity": "sha512-bKiiFN7Hnoaist/rditTRBXz+GXKYuLd53/NB7Q6zHB/bifELJarSoRLkAUGElIJKl4PSr3lTh1g6zehh+rX0g==", "dev": true, + "license": "MIT", + "bin": { + "oxc_language_server": "bin/oxc_language_server", + "oxlint": "bin/oxlint" + }, "engines": { - "node": ">=0.1.14" + "node": ">=14.*" + }, + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxlint/darwin-arm64": "0.9.10", + "@oxlint/darwin-x64": "0.9.10", + "@oxlint/linux-arm64-gnu": "0.9.10", + "@oxlint/linux-arm64-musl": "0.9.10", + "@oxlint/linux-x64-gnu": "0.9.10", + "@oxlint/linux-x64-musl": "0.9.10", + "@oxlint/win32-arm64": "0.9.10", + "@oxlint/win32-x64": "0.9.10" } }, - "node_modules/regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", - "dev": true - }, - "node_modules/regjsparser": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", - "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { - "jsesc": "~0.5.0" + "p-try": "^2.0.0" }, - "bin": { - "regjsparser": "bin/parser" + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/reify": { - "version": "0.20.12", + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "license": "MIT", "dependencies": { - "acorn": "^6.1.1", - "acorn-dynamic-import": "^4.0.0", - "magic-string": "^0.25.3", - "semver": "^5.4.1" + "p-limit": "^2.2.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/reify/node_modules/acorn": { - "version": "6.4.2", + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, "engines": { - "node": ">=0.4.0" + "node": ">=6" } }, - "node_modules/reify/node_modules/acorn-dynamic-import": { - "version": "4.0.0", + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0" - } + "license": "BlueOak-1.0.0" }, - "node_modules/reify/node_modules/semver": { - "version": "5.7.1", + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10" + "node": ">=8" } }, - "node_modules/requires-port": { - "version": "1.0.0", + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true, "license": "MIT" }, - "node_modules/resolve": { - "version": "1.22.1", + "node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, - "bin": { - "resolve": "bin/resolve" + "engines": { + "node": "20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/resolve-from": { + "node_modules/path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/resumer": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha512-Fn9X8rX8yYF4m81rZCK/5VmrmsSbqS/i3rDLl6ZZHAXgC2nTAx3dhwG8q8odP/RmdLa2YrybDJaAMg+X1ajY3w==", + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, - "dependencies": { - "through": "~2.3.4" - } + "license": "ISC" }, - "node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "dependencies": { - "glob": "^7.1.3" + "license": "MIT", + "engines": { + "node": ">=8.6" }, - "bin": { - "rimraf": "bin.js" + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/robust-predicates": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-2.0.4.tgz", - "integrity": "sha512-l4NwboJM74Ilm4VKfbAtFeGq7aEjWL+5kVFcmgFA2MrdnQWx9iE/tUGvxY5HyMI7o/WpSIUFLbC5fbeaHgSCYg==" - }, - "node_modules/rollup": { - "version": "1.32.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz", - "integrity": "sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==", + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { - "@types/estree": "*", - "@types/node": "*", - "acorn": "^7.1.0" + "find-up": "^4.0.0" }, - "bin": { - "rollup": "dist/bin/rollup" + "engines": { + "node": ">=8" } }, - "node_modules/rollup-plugin-buble": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/rollup-plugin-buble/-/rollup-plugin-buble-0.19.8.tgz", - "integrity": "sha512-8J4zPk2DQdk3rxeZvxgzhHh/rm5nJkjwgcsUYisCQg1QbT5yagW+hehYEW7ZNns/NVbDCTv4JQ7h4fC8qKGOKw==", - "deprecated": "This module has been deprecated and is no longer maintained. Please use @rollup/plugin-buble.", + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", "dev": true, + "license": "MIT", "dependencies": { - "buble": "^0.19.8", - "rollup-pluginutils": "^2.3.3" + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" } }, - "node_modules/rollup-plugin-commonjs": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", - "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==", - "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-commonjs.", + "node_modules/pkg-types/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/platform": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "estree-walker": "^0.6.1", - "is-reference": "^1.1.2", - "magic-string": "^0.25.2", - "resolve": "^1.11.0", - "rollup-pluginutils": "^2.8.1" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, - "peerDependencies": { - "rollup": ">=1.12.0" + "engines": { + "node": "^10 || ^12 || >=14" } }, - "node_modules/rollup-plugin-node-resolve": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", - "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", - "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-node-resolve.", + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@types/resolve": "0.0.8", - "builtin-modules": "^3.1.0", - "is-module": "^1.0.0", - "resolve": "^1.11.1", - "rollup-pluginutils": "^2.8.1" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, - "peerDependencies": { - "rollup": ">=1.11.0" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/rollup-plugin-node-resolve/node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/rollup-pluginutils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, - "dependencies": { - "estree-walker": "^0.6.1" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" }, - "node_modules/rollup/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, "bin": { - "acorn": "bin/acorn" + "resolve": "bin/resolve" }, "engines": { - "node": ">=0.4.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.12.0" + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "node_modules/robust-predicates": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-2.0.4.tgz", + "integrity": "sha512-l4NwboJM74Ilm4VKfbAtFeGq7aEjWL+5kVFcmgFA2MrdnQWx9iE/tUGvxY5HyMI7o/WpSIUFLbC5fbeaHgSCYg==", + "license": "Unlicense" + }, + "node_modules/rollup": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz", + "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==", "dev": true, + "license": "MIT", "dependencies": { - "tslib": "^1.9.0" + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" }, "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/secure-compare": { - "version": "3.0.1", + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.53.3", + "@rollup/rollup-android-arm64": "4.53.3", + "@rollup/rollup-darwin-arm64": "4.53.3", + "@rollup/rollup-darwin-x64": "4.53.3", + "@rollup/rollup-freebsd-arm64": "4.53.3", + "@rollup/rollup-freebsd-x64": "4.53.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", + "@rollup/rollup-linux-arm-musleabihf": "4.53.3", + "@rollup/rollup-linux-arm64-gnu": "4.53.3", + "@rollup/rollup-linux-arm64-musl": "4.53.3", + "@rollup/rollup-linux-loong64-gnu": "4.53.3", + "@rollup/rollup-linux-ppc64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-musl": "4.53.3", + "@rollup/rollup-linux-s390x-gnu": "4.53.3", + "@rollup/rollup-linux-x64-gnu": "4.53.3", + "@rollup/rollup-linux-x64-musl": "4.53.3", + "@rollup/rollup-openharmony-arm64": "4.53.3", + "@rollup/rollup-win32-arm64-msvc": "4.53.3", + "@rollup/rollup-win32-ia32-msvc": "4.53.3", + "@rollup/rollup-win32-x64-gnu": "4.53.3", + "@rollup/rollup-win32-x64-msvc": "4.53.3", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, - "license": "MIT" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } }, "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/shell-quote": { - "version": "1.7.3", + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/side-channel": { - "version": "1.0.4", + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "license": "ISC", + "engines": { + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" }, "engines": { - "node": ">=6" + "node": ">= 10" } }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "license": "MIT" + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/spdx-correct": { - "version": "3.1.1", + "node_modules/source-map-js": { + "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==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "dev": true, - "license": "CC-BY-3.0" + "node_modules/splaytree": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/splaytree/-/splaytree-0.1.4.tgz", + "integrity": "sha512-D50hKrjZgBzqD3FT2Ek53f2dcDLAQT8SSGrzj3vidNH5ISRgceeGVJ2dQIthKOuayqFXfFjXheHNo4bbt9LhRQ==", + "license": "MIT" }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } + "license": "BSD-3-Clause" }, - "node_modules/spdx-license-ids": { - "version": "3.0.11", + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, - "license": "CC0-1.0" + "license": "MIT" }, - "node_modules/splaytree": { - "version": "0.1.4", + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, "license": "MIT" }, - "node_modules/split": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.0.tgz", - "integrity": "sha512-3SVfJe2A0WZg3D+ZEtXqYkvpSGAVaZ1MgufNCeHioBESCqQFsuT1VcQufiopBfJZqh92ZwQ6ddL378iUSbqVNQ==", + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, - "dependencies": { - "through": "2" - }, + "license": "MIT", "engines": { - "node": "*" + "node": ">=0.6.19" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, + "license": "MIT", "dependencies": { - "safe-buffer": "~5.1.0" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/string-width": { + "node_modules/string-width-cjs": { + "name": "string-width", "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -2794,20 +3445,29 @@ "node": ">=8" } }, - "node_modules/string-width/node_modules/ansi-regex": { + "node_modules/string-width-cjs/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/string-width/node_modules/strip-ansi": { + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -2815,83 +3475,57 @@ "node": ">=8" } }, - "node_modules/string.prototype.padend": { - "version": "3.1.3", + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.6.tgz", - "integrity": "sha512-8lMR2m+U0VJTPp6JjvJTtGyc4FIGq9CdRt7O9p6T0e6K4vjU+OP+SQJpbe/SBmRcCUIvNUnjsbmY6lnMp8MhsQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - }, - "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.5", + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "ansi-regex": "^5.0.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8" } }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.5", + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/strip-bom": { + "node_modules/strip-final-newline": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/strip-json-comments": { @@ -2899,6 +3533,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -2906,20 +3541,52 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-literal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.1.tgz", + "integrity": "sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, "license": "MIT", "engines": { @@ -2929,2959 +3596,557 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true, - "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", + "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=6.0.0" + "node": ">=14.0.0" } }, - "node_modules/table/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "node_modules/tinyqueue": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", + "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", + "license": "ISC" }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=14.0.0" } }, - "node_modules/table/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "is-number": "^7.0.0" }, "engines": { - "node": ">=6" + "node": ">=8.0" } }, - "node_modules/tap-out": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tap-out/-/tap-out-2.1.0.tgz", - "integrity": "sha512-LJE+TBoVbOWhwdz4+FQk40nmbIuxJLqaGvj3WauQw3NYYU5TdjoV3C0x/yq37YAvVyi+oeBXmWnxWSjJ7IEyUw==", + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, - "dependencies": { - "re-emitter": "1.1.3", - "readable-stream": "2.2.9", - "split": "1.0.0", - "trim": "0.0.1" - }, - "bin": { - "tap-out": "bin/cmd.js" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "node_modules/tap-parser": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-1.3.2.tgz", - "integrity": "sha512-DvP7UJFCyqFPVTWrX51mqQPHAA7vvm77bUsIGGtaLSpHVVvfP6c4Xej5ymt0dVLngE5NouPwCsDzOVW9Bnobuw==", + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", "dev": true, + "license": "MIT", "dependencies": { - "events-to-array": "^1.0.1", - "inherits": "~2.0.1", - "js-yaml": "^3.2.7" + "escape-string-regexp": "^1.0.2" }, - "bin": { - "tap-parser": "bin/cmd.js" - }, - "optionalDependencies": { - "readable-stream": "^2" - } - }, - "node_modules/tap-spec": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tap-spec/-/tap-spec-5.0.0.tgz", - "integrity": "sha512-zMDVJiE5I6Y4XGjlueGXJIX2YIkbDN44broZlnypT38Hj/czfOXrszHNNJBF/DXR8n+x6gbfSx68x04kIEHdrw==", - "dev": true, - "dependencies": { - "chalk": "^1.0.0", - "duplexer": "^0.1.1", - "figures": "^1.4.0", - "lodash": "^4.17.10", - "pretty-ms": "^2.1.0", - "repeat-string": "^1.5.2", - "tap-out": "^2.1.0", - "through2": "^2.0.0" - }, - "bin": { - "tap-spec": "bin/cmd.js", - "tspec": "bin/cmd.js" - } - }, - "node_modules/tap-spec/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/tap-spec/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/tap-spec/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, "engines": { - "node": ">=0.10.0" + "node": ">=14.17" } }, - "node_modules/tap-spec/node_modules/figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==", + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - }, + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 10.0.0" } }, - "node_modules/tap-spec/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" + "punycode": "^2.1.0" } }, - "node_modules/tap-spec/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "node_modules/validator": { + "version": "13.15.23", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.23.tgz", + "integrity": "sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">= 0.10" } }, - "node_modules/tap-status": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tap-status/-/tap-status-1.0.1.tgz", - "integrity": "sha512-NeLre7/Vs94RyjPn2VQMOhTp64RGs41VEXWHcqu9Zjaf23uosigbBhapj6d+JRKM09ccDgy+ZCMkDVh9+OPdlg==", + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", "dev": true, + "license": "MIT", "dependencies": { - "tap-parser": "^1.1.5", - "tape": "^4.0.0" + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { - "tap-status": "index.js" + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } } }, - "node_modules/tape": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.15.1.tgz", - "integrity": "sha512-k7F5pyr91n9D/yjSJwbLLYDCrTWXxMSXbbmHX2n334lSIc2rxeXyFkaBv4UuUd2gBYMrAOalPutAiCxC6q1qbw==", + "node_modules/vite-node": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.1.tgz", + "integrity": "sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "~1.0.2", - "deep-equal": "~1.1.1", - "defined": "~1.0.0", - "dotignore": "~0.1.2", - "for-each": "~0.3.3", - "glob": "~7.2.0", - "has": "~1.0.3", - "inherits": "~2.0.4", - "is-regex": "~1.1.4", - "minimist": "~1.2.6", - "object-inspect": "~1.12.0", - "resolve": "~1.22.0", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.2.5", - "through": "~2.3.8" + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" }, "bin": { - "tape": "bin/tape" + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/text-table": { - "version": "0.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "node_modules/vite-plugin-dts": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/vite-plugin-dts/-/vite-plugin-dts-3.9.1.tgz", + "integrity": "sha512-rVp2KM9Ue22NGWB8dNtWEr+KekN3rIgz1tWD050QnRGlriUCmaDwa7qA5zDEjbXg5lAXhYMSBJtx3q3hQIJZSg==", "dev": true, + "license": "MIT", "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "@microsoft/api-extractor": "7.43.0", + "@rollup/pluginutils": "^5.1.0", + "@vue/language-core": "^1.8.27", + "debug": "^4.3.4", + "kolorist": "^1.8.0", + "magic-string": "^0.30.8", + "vue-tsc": "^1.8.27" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "typescript": "*", + "vite": "*" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } } }, - "node_modules/through2/node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "node_modules/vitest": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.1.tgz", + "integrity": "sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==", "dev": true, + "license": "MIT", "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "@vitest/expect": "1.6.1", + "@vitest/runner": "1.6.1", + "@vitest/snapshot": "1.6.1", + "@vitest/spy": "1.6.1", + "@vitest/utils": "1.6.1", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.3", + "vite": "^5.0.0", + "vite-node": "1.6.1", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.6.1", + "@vitest/ui": "1.6.1", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } } }, - "node_modules/through2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "node_modules/vue-template-compiler": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", + "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", "dev": true, + "license": "MIT", "dependencies": { - "safe-buffer": "~5.1.0" + "de-indent": "^1.0.2", + "he": "^1.2.0" } }, - "node_modules/tinyqueue": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-1.2.3.tgz", - "integrity": "sha512-Qz9RgWuO9l8lT+Y9xvbzhPT2efIUIFd69N7eF7tJ9lnQl0iLj1M7peK7IoUGZL9DJHw9XftqLreccfxcQgYLxA==" - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "node_modules/vue-tsc": { + "version": "1.8.27", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.27.tgz", + "integrity": "sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==", "dev": true, + "license": "MIT", "dependencies": { - "os-tmpdir": "~1.0.2" + "@volar/typescript": "~1.11.1", + "@vue/language-core": "1.8.27", + "semver": "^7.5.4" }, - "engines": { - "node": ">=0.6.0" + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": "*" } }, - "node_modules/trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==", - "dev": true - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "node_modules/vue-tsc/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">= 0.8.0" + "node": ">=10" } }, - "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, "engines": { - "node": ">=8" + "node": ">= 8" } }, - "node_modules/typescript": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", - "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "why-is-node-running": "cli.js" }, "engines": { - "node": ">=4.2.0" + "node": ">=8" } }, - "node_modules/uglify-js": { - "version": "3.16.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.3.tgz", - "integrity": "sha512-uVbFqx9vvLhQg0iBaau9Z75AxWJ8tqM9AV890dIZCLApF4rTcyHwmAvLeEdYRs+BzYWu8Iw81F79ah0EfTXbaw==", + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, - "bin": { - "uglifyjs": "bin/uglifyjs" + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=0.8.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/unbox-primitive": { - "version": "1.0.2", + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, - "engines": { - "node": ">=4" - } + "license": "MIT" }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", - "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/union": { - "version": "0.5.0", + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { - "qs": "^6.4.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">= 0.8.0" + "node": ">=8" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, - "dependencies": { - "punycode": "^2.1.0" + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/url-join": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", - "integrity": "sha512-c2H1fIgpUdwFRIru9HFno5DT73Ok8hg5oOb5AT3ayIgvCRfxgs2jyt5Slw8kEB7j3QUr6yJmMPDT/odjk7jXow==", - "dev": true - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/z-schema": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", + "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", "dev": true, + "license": "MIT", "dependencies": { - "isexe": "^2.0.0" + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "validator": "^13.7.0" }, "bin": { - "which": "bin/which" + "z-schema": "bin/z-schema" + }, + "engines": { + "node": ">=8.0.0" + }, + "optionalDependencies": { + "commander": "^9.4.1" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", + "node_modules/z-schema/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "dev": true, "license": "MIT", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, + "optional": true, "engines": { - "node": ">=4" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", - "dev": true - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@turf/union": { - "version": "4.6.0", - "dev": true, - "requires": { - "jsts": "1.3.0" - } - }, - "@types/estree": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", - "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", - "dev": true - }, - "@types/geojson": { - "version": "1.0.6", - "dev": true - }, - "@types/node": { - "version": "17.0.45", - "dev": true - }, - "@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "acorn": { - "version": "8.7.1", - "dev": true, - "peer": true - }, - "acorn-jsx": { - "version": "5.3.2", - "dev": true, - "requires": {} - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, - "async": { - "version": "2.6.4", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "balanced-match": { - "version": "1.0.2", - "dev": true - }, - "basic-auth": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", - "integrity": "sha512-CtGuTyWf3ig+sgRyC7uP6DM3N+5ur/p8L+FPfsd+BbIfIs74TFfCajZTHnCw6K5dqM0bZEbRIqRy1fAdiUJhTA==", - "dev": true - }, - "benchmark": { - "version": "2.1.4", - "dev": true, - "requires": { - "lodash": "^4.17.4", - "platform": "^1.3.3" - } - }, - "brace-expansion": { - "version": "1.1.11", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buble": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/buble/-/buble-0.19.8.tgz", - "integrity": "sha512-IoGZzrUTY5fKXVkgGHw3QeXFMUNBFv+9l8a4QJKG1JhG3nCMHTdEX1DCOg8568E2Q9qvAQIiSokv6Jsgx8p2cA==", - "dev": true, - "requires": { - "acorn": "^6.1.1", - "acorn-dynamic-import": "^4.0.0", - "acorn-jsx": "^5.0.1", - "chalk": "^2.4.2", - "magic-string": "^0.25.3", - "minimist": "^1.2.0", - "os-homedir": "^2.0.0", - "regexpu-core": "^4.5.4" - }, - "dependencies": { - "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", - "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", - "dev": true, - "requires": {} - } - } - }, - "buffer-shims": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g==", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", - "dev": true - }, - "call-bind": { - "version": "1.0.2", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "comment-parser": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.7.6.tgz", - "integrity": "sha512-GKNxVA7/iuTnAqGADlTWX4tkhzxZKXp5fLJqKTlQLHkE65XDUKutZ3BHaJC5IGcper2tT3QRD1xr4o3jNpgXXg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "dev": true - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "corser": { - "version": "2.0.1", - "dev": true - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "debug": { - "version": "4.3.4", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "define-properties": { - "version": "1.1.4", - "dev": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==", - "dev": true - }, - "doctrine": { - "version": "3.0.0", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dotignore": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz", - "integrity": "sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==", - "dev": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true - }, - "ecstatic": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-3.3.2.tgz", - "integrity": "sha512-fLf9l1hnwrHI2xn9mEDT7KIi22UDqA2jaCwyCbSUJh9a1V+LEUSL/JO/6TIz/QyuBURWUHrFL5Kg2TtO1bkkog==", - "dev": true, - "requires": { - "he": "^1.1.1", - "mime": "^1.6.0", - "minimist": "^1.1.0", - "url-join": "^2.0.5" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.20.1", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.3", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - } - }, - "eslint-plugin-import-order": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import-order/-/eslint-plugin-import-order-2.1.4.tgz", - "integrity": "sha512-cHThJ45zFx5UtRZ+Jd6XO89bLriKkdckAHZoSxknlK3BELmAO6Gqe74A7j8rvL+1PEyNJF3Fsil/Rjwx8cqOow==", - "dev": true, - "requires": { - "builtin-modules": "^1.1.1", - "lodash.cond": "^4.2.0", - "lodash.find": "^4.2.0" - } - }, - "eslint-plugin-jsdoc": { - "version": "20.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-20.4.0.tgz", - "integrity": "sha512-c/fnEpwWLFeQn+A7pb1qLOdyhovpqGCWCeUv1wtzFNL5G+xedl9wHUnXtp3b1sGHolVimi9DxKVTuhK/snXoOw==", - "dev": true, - "requires": { - "comment-parser": "^0.7.2", - "debug": "^4.1.1", - "jsdoctypeparser": "^6.1.0", - "lodash": "^4.17.15", - "object.entries-ponyfill": "^1.0.1", - "regextras": "^0.7.0", - "semver": "^6.3.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "eslint-plugin-promise": { - "version": "3.8.0", - "dev": true - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "dependencies": { - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - } - } - }, - "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - }, - "espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "dev": true - }, - "estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "dev": true - }, - "eventemitter3": { - "version": "4.0.7", - "dev": true - }, - "events-to-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz", - "integrity": "sha512-inRWzRY7nG+aXZxBzEqYKB3HPgwflZRopAjDCHv0whhRx+MTUr1ei0ICZUypdyE0HRm4L2d5VEcIqLD6yl+BFA==", - "dev": true - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "requires": { - "flat-cache": "^2.0.1" - } - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "node": "^12.20.0 || >=14" } - }, - "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "follow-redirects": { - "version": "1.15.1", - "dev": true - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "dev": true - }, - "function.prototype.name": { - "version": "1.1.5", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - } - }, - "functional-red-black-tree": { - "version": "1.0.1", - "dev": true - }, - "functions-have-names": { - "version": "1.2.3", - "dev": true - }, - "geojson-project": { - "version": "1.0.1", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.2", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "requires": { - "type-fest": "^0.8.1" - } - }, - "graceful-fs": { - "version": "4.2.10", - "dev": true - }, - "has": { - "version": "1.0.3", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - } - } - }, - "has-bigints": { - "version": "1.0.2", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "has-property-descriptors": { - "version": "1.0.0", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.3", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "hosted-git-info": { - "version": "2.8.9", - "dev": true - }, - "http-proxy": { - "version": "1.18.1", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-server": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.12.3.tgz", - "integrity": "sha512-be0dKG6pni92bRjq0kvExtj/NrrAd28/8fCXkaI/4piTwQMSDSLMhWyW0NI1V+DBI3aa1HMlQu46/HjVLfmugA==", - "dev": true, - "requires": { - "basic-auth": "^1.0.3", - "colors": "^1.4.0", - "corser": "^2.0.1", - "ecstatic": "^3.3.2", - "http-proxy": "^1.18.0", - "minimist": "^1.2.5", - "opener": "^1.5.1", - "portfinder": "^1.0.25", - "secure-compare": "3.0.1", - "union": "~0.5.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "internal-slot": { - "version": "1.0.3", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.4", - "dev": true - }, - "is-core-module": { - "version": "2.9.0", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.5", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "dev": true - }, - "is-finite": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true - }, - "is-negative-zero": { - "version": "2.0.2", - "dev": true - }, - "is-number-object": { - "version": "1.0.7", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "requires": { - "@types/estree": "*" - } - }, - "is-regex": { - "version": "1.1.4", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.2", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-string": { - "version": "1.0.7", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-weakref": { - "version": "1.0.2", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsdoctypeparser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-6.1.0.tgz", - "integrity": "sha512-UCQBZ3xCUBv/PLfwKAJhp6jmGOSLFNKzrotXGNgbKhWvz27wPsCsVeP7gIcHPElQw2agBmynAitXqhxR58XAmA==", - "dev": true - }, - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "dev": true - }, - "json-stringify-pretty-compact": { - "version": "2.0.0", - "dev": true - }, - "jsts": { - "version": "1.3.0", - "dev": true - }, - "leaflet": { - "version": "1.8.0", - "dev": true - }, - "leaflet-editable": { - "version": "1.2.0", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "load-json-file": { - "version": "2.0.0", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "dev": true - }, - "lodash.cond": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", - "integrity": "sha512-RWjUhzGbzG/KfDwk+onqdXvrsNv47G9UCMJgSKalPTSqJQyxZhQophG9jgqLf+15TIbZ5a/yG2YKOWsH3dVy9A==", - "dev": true - }, - "lodash.find": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz", - "integrity": "sha512-yaRZoAV3Xq28F1iafWN1+a0rflOej93l1DQUejs3SZ41h2O9UJBoS9aueGjPDgAl4B6tPC0NuuchLKaDQQ3Isg==", - "dev": true - }, - "magic-string": { - "version": "0.25.9", - "dev": true, - "requires": { - "sourcemap-codec": "^1.4.8" - } - }, - "memorystream": { - "version": "0.3.1", - "dev": true - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6", - "dev": true - }, - "mkdirp": { - "version": "0.5.6", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "ms": { - "version": "2.1.2", - "dev": true - }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "dev": true - } - } - }, - "npm-run-all": { - "version": "4.1.5", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "memorystream": "^0.3.1", - "minimatch": "^3.0.4", - "pidtree": "^0.3.0", - "read-pkg": "^3.0.0", - "shell-quote": "^1.6.1", - "string.prototype.padend": "^3.0.0" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true - }, - "object-inspect": { - "version": "1.12.2", - "dev": true - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "dev": true - }, - "object.assign": { - "version": "4.1.2", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.entries-ponyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.entries-ponyfill/-/object.entries-ponyfill-1.0.1.tgz", - "integrity": "sha512-j0ixssXc5GirDWhB2cLVPsOs9jx61G/iRndyMdToTsjMYY8BQmG1Ke6mwqXmpDiP8icye1YCR94NswNaa/yyzA==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "opener": { - "version": "1.5.2", - "dev": true - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "os-homedir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-2.0.0.tgz", - "integrity": "sha512-saRNz0DSC5C/I++gFIaJTXoFJMRwiP5zHar5vV3xQ2TkgEw6hDCcU5F272JjUylpiVgBrZNQHnfjkLabTfb92Q==", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "parse-ms": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz", - "integrity": "sha512-LpH1Cf5EYuVjkBvCDBYvkUPh+iv2bk3FHflxHkpCYT0/FZ1d3N3uJaLiHr4yGuMcFUhv6eAivitTvWZI4B/chg==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "dev": true - } - } - }, - "pidtree": { - "version": "0.3.1", - "dev": true - }, - "pify": { - "version": "2.3.0", - "dev": true - }, - "platform": { - "version": "1.3.6", - "dev": true - }, - "plur": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz", - "integrity": "sha512-qSnKBSZeDY8ApxwhfVIwKwF36KVJqb1/9nzYYq3j3vdwocULCXT8f8fQGkiw1Nk9BGfxiDagEe/pwakA+bOBqw==", - "dev": true - }, - "portfinder": { - "version": "1.0.28", - "dev": true, - "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true - }, - "pretty-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz", - "integrity": "sha512-H2enpsxzDhuzRl3zeSQpQMirn8dB0Z/gxW96j06tMfTviUWvX14gjKb7qd1gtkUyYhDPuoNe00K5PqNvy2oQNg==", - "dev": true, - "requires": { - "is-finite": "^1.0.1", - "parse-ms": "^1.0.0", - "plur": "^1.0.0" - } - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "qs": { - "version": "6.11.0", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, - "re-emitter": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/re-emitter/-/re-emitter-1.1.3.tgz", - "integrity": "sha512-bHJul9CWcocrS+w5e5QrKYXV9NkbSA9hxSEyhYuctwm6keY9NXR2Xt/4A0vbMP0QvuwyfEyb4bkowYXv1ziEbg==", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "dependencies": { - "load-json-file": { - "version": "4.0.0", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "pify": { - "version": "3.0.0", - "dev": true - } - } - }, - "readable-stream": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", - "integrity": "sha512-iuxqX7b7FYt08AriYECxUsK9KTXE3A/FenxIa3IPmvANHxaTP/wGIwwf+IidvvIDk/MsCp/oEV6A8CXo4SDcCg==", - "dev": true, - "requires": { - "buffer-shims": "~1.0.0", - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~1.0.0", - "util-deprecate": "~1.0.1" - } - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", - "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", - "dev": true, - "requires": { - "regenerate": "^1.4.2" - } - }, - "regexp.prototype.flags": { - "version": "1.4.3", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - } - }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true - }, - "regexpu-core": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", - "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", - "dev": true, - "requires": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^9.0.0", - "regjsgen": "^0.5.2", - "regjsparser": "^0.7.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" - } - }, - "regextras": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.7.1.tgz", - "integrity": "sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w==", - "dev": true - }, - "regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", - "dev": true - }, - "regjsparser": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", - "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - } - }, - "reify": { - "version": "0.20.12", - "dev": true, - "requires": { - "acorn": "^6.1.1", - "acorn-dynamic-import": "^4.0.0", - "magic-string": "^0.25.3", - "semver": "^5.4.1" - }, - "dependencies": { - "acorn": { - "version": "6.4.2", - "dev": true - }, - "acorn-dynamic-import": { - "version": "4.0.0", - "dev": true, - "requires": {} - }, - "semver": { - "version": "5.7.1", - "dev": true - } - } - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "dev": true - }, - "resolve": { - "version": "1.22.1", - "dev": true, - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "resumer": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha512-Fn9X8rX8yYF4m81rZCK/5VmrmsSbqS/i3rDLl6ZZHAXgC2nTAx3dhwG8q8odP/RmdLa2YrybDJaAMg+X1ajY3w==", - "dev": true, - "requires": { - "through": "~2.3.4" - } - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "robust-predicates": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-2.0.4.tgz", - "integrity": "sha512-l4NwboJM74Ilm4VKfbAtFeGq7aEjWL+5kVFcmgFA2MrdnQWx9iE/tUGvxY5HyMI7o/WpSIUFLbC5fbeaHgSCYg==" - }, - "rollup": { - "version": "1.32.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz", - "integrity": "sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/node": "*", - "acorn": "^7.1.0" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - } - } - }, - "rollup-plugin-buble": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/rollup-plugin-buble/-/rollup-plugin-buble-0.19.8.tgz", - "integrity": "sha512-8J4zPk2DQdk3rxeZvxgzhHh/rm5nJkjwgcsUYisCQg1QbT5yagW+hehYEW7ZNns/NVbDCTv4JQ7h4fC8qKGOKw==", - "dev": true, - "requires": { - "buble": "^0.19.8", - "rollup-pluginutils": "^2.3.3" - } - }, - "rollup-plugin-commonjs": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", - "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==", - "dev": true, - "requires": { - "estree-walker": "^0.6.1", - "is-reference": "^1.1.2", - "magic-string": "^0.25.2", - "resolve": "^1.11.0", - "rollup-pluginutils": "^2.8.1" - } - }, - "rollup-plugin-node-resolve": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", - "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", - "dev": true, - "requires": { - "@types/resolve": "0.0.8", - "builtin-modules": "^3.1.0", - "is-module": "^1.0.0", - "resolve": "^1.11.1", - "rollup-pluginutils": "^2.8.1" - }, - "dependencies": { - "builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true - } - } - }, - "rollup-pluginutils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", - "dev": true, - "requires": { - "estree-walker": "^0.6.1" - } - }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "secure-compare": { - "version": "3.0.1", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true - }, - "shell-quote": { - "version": "1.7.3", - "dev": true - }, - "side-channel": { - "version": "1.0.4", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true - } - } - }, - "sourcemap-codec": { - "version": "1.4.8", - "dev": true - }, - "spdx-correct": { - "version": "3.1.1", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.11", - "dev": true - }, - "splaytree": { - "version": "0.1.4" - }, - "split": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.0.tgz", - "integrity": "sha512-3SVfJe2A0WZg3D+ZEtXqYkvpSGAVaZ1MgufNCeHioBESCqQFsuT1VcQufiopBfJZqh92ZwQ6ddL378iUSbqVNQ==", - "dev": true, - "requires": { - "through": "2" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "string.prototype.padend": { - "version": "3.1.3", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "string.prototype.trim": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.6.tgz", - "integrity": "sha512-8lMR2m+U0VJTPp6JjvJTtGyc4FIGq9CdRt7O9p6T0e6K4vjU+OP+SQJpbe/SBmRcCUIvNUnjsbmY6lnMp8MhsQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - } - }, - "string.prototype.trimend": { - "version": "1.0.5", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.5", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "dev": true - }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - } - } - }, - "tap-out": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tap-out/-/tap-out-2.1.0.tgz", - "integrity": "sha512-LJE+TBoVbOWhwdz4+FQk40nmbIuxJLqaGvj3WauQw3NYYU5TdjoV3C0x/yq37YAvVyi+oeBXmWnxWSjJ7IEyUw==", - "dev": true, - "requires": { - "re-emitter": "1.1.3", - "readable-stream": "2.2.9", - "split": "1.0.0", - "trim": "0.0.1" - } - }, - "tap-parser": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-1.3.2.tgz", - "integrity": "sha512-DvP7UJFCyqFPVTWrX51mqQPHAA7vvm77bUsIGGtaLSpHVVvfP6c4Xej5ymt0dVLngE5NouPwCsDzOVW9Bnobuw==", - "dev": true, - "requires": { - "events-to-array": "^1.0.1", - "inherits": "~2.0.1", - "js-yaml": "^3.2.7", - "readable-stream": "^2" - } - }, - "tap-spec": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tap-spec/-/tap-spec-5.0.0.tgz", - "integrity": "sha512-zMDVJiE5I6Y4XGjlueGXJIX2YIkbDN44broZlnypT38Hj/czfOXrszHNNJBF/DXR8n+x6gbfSx68x04kIEHdrw==", - "dev": true, - "requires": { - "chalk": "^1.0.0", - "duplexer": "^0.1.1", - "figures": "^1.4.0", - "lodash": "^4.17.10", - "pretty-ms": "^2.1.0", - "repeat-string": "^1.5.2", - "tap-out": "^2.1.0", - "through2": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true - } - } - }, - "tap-status": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tap-status/-/tap-status-1.0.1.tgz", - "integrity": "sha512-NeLre7/Vs94RyjPn2VQMOhTp64RGs41VEXWHcqu9Zjaf23uosigbBhapj6d+JRKM09ccDgy+ZCMkDVh9+OPdlg==", - "dev": true, - "requires": { - "tap-parser": "^1.1.5", - "tape": "^4.0.0" - } - }, - "tape": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.15.1.tgz", - "integrity": "sha512-k7F5pyr91n9D/yjSJwbLLYDCrTWXxMSXbbmHX2n334lSIc2rxeXyFkaBv4UuUd2gBYMrAOalPutAiCxC6q1qbw==", - "dev": true, - "requires": { - "call-bind": "~1.0.2", - "deep-equal": "~1.1.1", - "defined": "~1.0.0", - "dotignore": "~0.1.2", - "for-each": "~0.3.3", - "glob": "~7.2.0", - "has": "~1.0.3", - "inherits": "~2.0.4", - "is-regex": "~1.1.4", - "minimist": "~1.2.6", - "object-inspect": "~1.12.0", - "resolve": "~1.22.0", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.2.5", - "through": "~2.3.8" - } - }, - "text-table": { - "version": "0.2.0", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "tinyqueue": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-1.2.3.tgz", - "integrity": "sha512-Qz9RgWuO9l8lT+Y9xvbzhPT2efIUIFd69N7eF7tJ9lnQl0iLj1M7peK7IoUGZL9DJHw9XftqLreccfxcQgYLxA==" - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==", - "dev": true - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - }, - "typescript": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", - "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", - "dev": true - }, - "uglify-js": { - "version": "3.16.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.3.tgz", - "integrity": "sha512-uVbFqx9vvLhQg0iBaau9Z75AxWJ8tqM9AV890dIZCLApF4rTcyHwmAvLeEdYRs+BzYWu8Iw81F79ah0EfTXbaw==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.2", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", - "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", - "dev": true - }, - "union": { - "version": "0.5.0", - "dev": true, - "requires": { - "qs": "^6.4.0" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "url-join": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", - "integrity": "sha512-c2H1fIgpUdwFRIru9HFno5DT73Ok8hg5oOb5AT3ayIgvCRfxgs2jyt5Slw8kEB7j3QUr6yJmMPDT/odjk7jXow==", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "v8-compile-cache": { - "version": "2.3.0", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true } } } diff --git a/package.json b/package.json index c22e397..0c749f5 100644 --- a/package.json +++ b/package.json @@ -1,29 +1,37 @@ { "name": "martinez-polygon-clipping", - "version": "0.7.4", + "version": "0.8.0", "description": "Martinez polygon clipping algorithm, does boolean operation on polygons (multipolygons, polygons with holes etc): intersection, union, difference, xor", - "main": "dist/martinez.umd.js", - "browser": "dist/martinez.umd.js", - "module": "index.js", - "jsnext:main": "index.js", - "types": "index.d.ts", + "main": "dist/martinez.cjs", + "browser": "dist/martinez.js", + "module": "dist/martinez.js", + "types": "dist/index.d.ts", + "type": "module", + "exports": { + ".": { + "import": "./dist/martinez.js", + "require": "./dist/martinez.cjs", + "types": "./dist/index.d.ts" + } + }, "files": [ - "index.d.ts", - "index.js", - "src/", "dist/" ], "scripts": { - "test": "tape -r reify buble/register test/*.test.js | tap-spec && npm run ts", - "ts": "tsc index.d.ts", - "bench": "node --require reify bench.js", - "lint": "eslint ./src/", - "watch": "rollup -c -w", - "serve": "http-server -p 3000", - "start": "run-p watch serve", - "build": "npm run lint && rollup -c && npm run min", - "min": "uglifyjs ./dist/martinez.umd.js -o ./dist/martinez.min.js -m --comments", - "prepublishOnly": "npm run lint && npm run test && npm run build" + "test": "vitest", + "test:ui": "vitest --ui", + "test:run": "vitest run", + "bench": "vitest bench", + "lint": "oxlint src test bench demo", + "typecheck": "tsc --noEmit", + "dev": "vite --mode demo", + "dev:demo": "vite --mode demo", + "build": "vite build", + "build:demo": "vite build --mode demo", + "preview": "vite preview", + "preview:demo": "vite preview --outDir dist/demo", + "deploy:demo": "npm run build:demo && gh-pages --nojekyll -d dist/demo -t -m 'Deploy demo'", + "prepublishOnly": "npm run lint && npm run test:run && npm run build" }, "keywords": [ "polygon", @@ -45,33 +53,27 @@ "devDependencies": { "@turf/union": "^4.6.0", "@types/geojson": "^1.0.2", + "@types/glob": "^8.1.0", + "@types/jsts": "0.17.24", + "@types/leaflet": "1.9.21", + "@types/node": "^20.0.0", + "@vitest/ui": "^1.0.0", "benchmark": "^2.1.4", - "buble": "^0.19.3", - "eslint": "^6.8.0", - "eslint-plugin-import-order": "^2.1.4", - "eslint-plugin-jsdoc": "^20.0.2", - "eslint-plugin-promise": "^3.8.0", "geojson-project": "^1.0.0", - "http-server": "^0.12.1", + "gh-pages": "^6.1.1", + "glob": "^11.0.3", "json-stringify-pretty-compact": "^2.0.0", - "leaflet": "^1.2.0", - "leaflet-editable": "^1.1.0", - "load-json-file": "^2.0.0", - "npm-run-all": "^4.1.5", - "reify": "^0.20.12", - "rollup": "^1.28.0", - "rollup-plugin-buble": "^0.19.8", - "rollup-plugin-commonjs": "^10.1.0", - "rollup-plugin-node-resolve": "^5.2.0", - "tap-spec": "^5.0.0", - "tap-status": "^1.0.1", - "tape": "^4.12.1", - "typescript": "^3.7.4", - "uglify-js": "^3.3.21" + "leaflet": "1.9.4", + "leaflet-editable": "^1.3.2", + "oxlint": "^0.9.10", + "typescript": "^5.0.0", + "vite": "^5.0.0", + "vite-plugin-dts": "^3.0.0", + "vitest": "^1.0.0" }, "dependencies": { "robust-predicates": "^2.0.4", "splaytree": "^0.1.4", - "tinyqueue": "^1.2.0" + "tinyqueue": "3.0.0" } } diff --git a/rollup.config.js b/rollup.config.js deleted file mode 100644 index 06a3f84..0000000 --- a/rollup.config.js +++ /dev/null @@ -1,49 +0,0 @@ -import resolve from 'rollup-plugin-node-resolve'; -import commonjs from 'rollup-plugin-commonjs'; -import buble from 'rollup-plugin-buble'; -import { version, author, license, description } from './package.json'; - -const name = 'martinez'; - -const banner = `\ -/** - * ${name} v${version} - * ${description} - * - * @author ${author} - * @license ${license} - * @preserve - */ -`; - -module.exports = [{ - input: './index.js', - output: { - file: `dist/${name}.umd.js`, - name: 'martinez', - sourcemap: true, - format: 'umd', - banner - }, - plugins: [ - resolve(), // so Rollup can find external libs - commonjs(), // so Rollup can convert commonJS to an ES module - buble() - ] -}, { - input: 'demo/js/index.js', - output: { - file: 'demo/js/bundle.js', - format: 'iife', - globals: { - leaflet: 'L', - jsts: 'jsts' - } - }, - external: ['jsts', 'leaflet'], - plugins: [ - resolve(), // so Rollup can find external libs - commonjs(), // so Rollup can convert commonJS to an ES module - buble() - ] -}]; diff --git a/src/compare_events.js b/src/compare_events.ts similarity index 72% rename from src/compare_events.js rename to src/compare_events.ts index fee7fa2..169bc01 100644 --- a/src/compare_events.js +++ b/src/compare_events.ts @@ -1,11 +1,13 @@ import signedArea from './signed_area'; +import SweepEvent from './sweep_event'; +import { Position } from './types'; /** * @param {SweepEvent} e1 * @param {SweepEvent} e2 - * @return {Number} + * @return {number} */ -export default function compareEvents(e1, e2) { +export default function compareEvents(e1: SweepEvent, e2: SweepEvent): number { const p1 = e1.point; const p2 = e2.point; @@ -22,7 +24,7 @@ export default function compareEvents(e1, e2) { /* eslint-disable no-unused-vars */ -function specialCases(e1, e2, p1, p2) { +function specialCases(e1: SweepEvent, e2: SweepEvent, p1: Position, p2: Position): number { // Same coordinates, but one is a left endpoint and the other is // a right endpoint. The right endpoint is processed first if (e1.left !== e2.left) @@ -33,9 +35,9 @@ function specialCases(e1, e2, p1, p2) { // Same coordinates, both events // are left endpoints or right endpoints. // not collinear - if (signedArea(p1, e1.otherEvent.point, e2.otherEvent.point) !== 0) { + if (signedArea(p1, e1.otherEvent!.point, e2.otherEvent!.point) !== 0) { // the event associate to the bottom segment is processed first - return (!e1.isBelow(e2.otherEvent.point)) ? 1 : -1; + return (!e1.isBelow(e2.otherEvent!.point)) ? 1 : -1; } return (!e1.isSubject && e2.isSubject) ? 1 : -1; diff --git a/src/compare_segments.js b/src/compare_segments.ts similarity index 69% rename from src/compare_segments.js rename to src/compare_segments.ts index 47e1d71..20a9754 100644 --- a/src/compare_segments.js +++ b/src/compare_segments.ts @@ -1,22 +1,24 @@ import signedArea from './signed_area'; import compareEvents from './compare_events'; import equals from './equals'; +import SweepEvent from './sweep_event'; +import { Position } from './types'; /** * @param {SweepEvent} le1 * @param {SweepEvent} le2 - * @return {Number} + * @return {number} */ -export default function compareSegments(le1, le2) { +export default function compareSegments(le1: SweepEvent, le2: SweepEvent): number { if (le1 === le2) return 0; // Segments are not collinear - if (signedArea(le1.point, le1.otherEvent.point, le2.point) !== 0 || - signedArea(le1.point, le1.otherEvent.point, le2.otherEvent.point) !== 0) { + if (signedArea(le1.point, le1.otherEvent!.point, le2.point) !== 0 || + signedArea(le1.point, le1.otherEvent!.point, le2.otherEvent!.point) !== 0) { // If they share their left endpoint use the right endpoint to sort - if (equals(le1.point, le2.point)) return le1.isBelow(le2.otherEvent.point) ? -1 : 1; + if (equals(le1.point, le2.point)) return le1.isBelow(le2.otherEvent!.point) ? -1 : 1; // Different left endpoint: use the left endpoint to sort if (le1.point[0] === le2.point[0]) return le1.point[1] < le2.point[1] ? -1 : 1; @@ -31,11 +33,11 @@ export default function compareSegments(le1, le2) { } if (le1.isSubject === le2.isSubject) { // same polygon - let p1 = le1.point, p2 = le2.point; + let p1: Position = le1.point, p2: Position = le2.point; if (p1[0] === p2[0] && p1[1] === p2[1]/*equals(le1.point, le2.point)*/) { - p1 = le1.otherEvent.point; p2 = le2.otherEvent.point; + p1 = le1.otherEvent!.point; p2 = le2.otherEvent!.point; if (p1[0] === p2[0] && p1[1] === p2[1]) return 0; - else return le1.contourId > le2.contourId ? 1 : -1; + else return (le1.contourId ?? 0) > (le2.contourId ?? 0) ? 1 : -1; } } else { // Segments are collinear, but belong to separate polygons return le1.isSubject ? -1 : 1; diff --git a/src/compute_fields.js b/src/compute_fields.ts similarity index 65% rename from src/compute_fields.js rename to src/compute_fields.ts index 10d8eb9..70d62e8 100644 --- a/src/compute_fields.js +++ b/src/compute_fields.ts @@ -2,42 +2,44 @@ import { NORMAL, SAME_TRANSITION, DIFFERENT_TRANSITION, - NON_CONTRIBUTING -} from './edge_type'; -import { - INTERSECTION, - UNION, - DIFFERENCE, - XOR -} from './operation'; + NON_CONTRIBUTING, +} from "./edge_type"; +import { INTERSECTION, UNION, DIFFERENCE, XOR } from "./operation"; +import SweepEvent from "./sweep_event"; /** * @param {SweepEvent} event - * @param {SweepEvent} prev - * @param {Operation} operation + * @param {SweepEvent | null} prev + * @param {number} operation */ -export default function computeFields (event, prev, operation) { +export default function computeFields( + event: SweepEvent, + prev: SweepEvent | null, + operation: number +): void { // compute inOut and otherInOut fields if (prev === null) { - event.inOut = false; + event.inOut = false; event.otherInOut = true; - // previous line segment in sweepline belongs to the same polygon + // previous line segment in sweepline belongs to the same polygon } else { if (event.isSubject === prev.isSubject) { - event.inOut = !prev.inOut; + event.inOut = !prev.inOut; event.otherInOut = prev.otherInOut; - // previous line segment in sweepline belongs to the clipping polygon + // previous line segment in sweepline belongs to the clipping polygon } else { - event.inOut = !prev.otherInOut; + event.inOut = !prev.otherInOut; event.otherInOut = prev.isVertical() ? !prev.inOut : prev.inOut; } // compute prevInResult field if (prev) { - event.prevInResult = (!inResult(prev, operation) || prev.isVertical()) - ? prev.prevInResult : prev; + event.prevInResult = + !inResult(prev, operation) || prev.isVertical() + ? prev.prevInResult + : prev; } } @@ -50,7 +52,6 @@ export default function computeFields (event, prev, operation) { } } - /* eslint-disable indent */ function inResult(event, operation) { switch (event.type) { @@ -63,8 +64,10 @@ function inResult(event, operation) { case DIFFERENCE: // return (event.isSubject && !event.otherInOut) || // (!event.isSubject && event.otherInOut); - return (event.isSubject && event.otherInOut) || - (!event.isSubject && !event.otherInOut); + return ( + (event.isSubject && event.otherInOut) || + (!event.isSubject && !event.otherInOut) + ); case XOR: return true; } @@ -80,7 +83,6 @@ function inResult(event, operation) { } /* eslint-enable indent */ - function determineResultTransition(event, operation) { let thisIn = !event.inOut; let thatIn = !event.otherInOut; @@ -88,11 +90,14 @@ function determineResultTransition(event, operation) { let isIn; switch (operation) { case INTERSECTION: - isIn = thisIn && thatIn; break; + isIn = thisIn && thatIn; + break; case UNION: - isIn = thisIn || thatIn; break; + isIn = thisIn || thatIn; + break; case XOR: - isIn = thisIn ^ thatIn; break; + isIn = thisIn !== thatIn; + break; case DIFFERENCE: if (event.isSubject) { isIn = thisIn && !thatIn; diff --git a/src/connect_edges.js b/src/connect_edges.ts similarity index 89% rename from src/connect_edges.js rename to src/connect_edges.ts index 0ce5c43..d4b87a0 100644 --- a/src/connect_edges.js +++ b/src/connect_edges.ts @@ -1,17 +1,18 @@ import compareEvents from './compare_events'; import Contour from './contour'; +import SweepEvent from './sweep_event'; /** - * @param {Array.} sortedEvents - * @return {Array.} + * @param {SweepEvent[]} sortedEvents + * @return {SweepEvent[]} */ -function orderEvents(sortedEvents) { - let event, i, len, tmp; - const resultEvents = []; +function orderEvents(sortedEvents: SweepEvent[]): SweepEvent[] { + let event: SweepEvent, i: number, len: number, tmpEvent: SweepEvent, tmpPos: number; + const resultEvents: SweepEvent[] = []; for (i = 0, len = sortedEvents.length; i < len; i++) { event = sortedEvents[i]; if ((event.left && event.inResult) || - (!event.left && event.otherEvent.inResult)) { + (!event.left && event.otherEvent!.inResult)) { resultEvents.push(event); } } @@ -22,9 +23,9 @@ function orderEvents(sortedEvents) { for (i = 0, len = resultEvents.length; i < len; i++) { if ((i + 1) < len && compareEvents(resultEvents[i], resultEvents[i + 1]) === 1) { - tmp = resultEvents[i]; + tmpEvent = resultEvents[i]; resultEvents[i] = resultEvents[i + 1]; - resultEvents[i + 1] = tmp; + resultEvents[i + 1] = tmpEvent; sorted = false; } } @@ -41,9 +42,9 @@ function orderEvents(sortedEvents) { for (i = 0, len = resultEvents.length; i < len; i++) { event = resultEvents[i]; if (!event.left) { - tmp = event.otherPos; - event.otherPos = event.otherEvent.otherPos; - event.otherEvent.otherPos = tmp; + tmpPos = event.otherPos; + event.otherPos = event.otherEvent!.otherPos; + event.otherEvent!.otherPos = tmpPos; } } diff --git a/src/contour.js b/src/contour.ts similarity index 56% rename from src/contour.js rename to src/contour.ts index a4c96ce..e249155 100644 --- a/src/contour.js +++ b/src/contour.ts @@ -1,4 +1,10 @@ +import { Position } from './types'; + export default class Contour { + public points: Position[]; + public holeIds: number[]; + public holeOf: Contour | null; + public depth: number | null; /** * Contour @@ -12,7 +18,7 @@ export default class Contour { this.depth = null; } - isExterior() { + isExterior(): boolean { return this.holeOf == null; } diff --git a/src/debug_utils.js b/src/debug_utils.ts similarity index 89% rename from src/debug_utils.js rename to src/debug_utils.ts index 674a50c..3218857 100644 --- a/src/debug_utils.js +++ b/src/debug_utils.ts @@ -1,5 +1,5 @@ /* eslint-disable */ -export function renderPoints(possiblePoints, prop) { +export function renderPoints(possiblePoints: any[], prop: string): void { var map = window.map; var points = window.points; if (!map) return; @@ -16,7 +16,7 @@ export function renderPoints(possiblePoints, prop) { }); }; -export function renderSweepLine(sweepLine, pos, event) { +export function renderSweepLine(sweepLine: any[], pos: any, event: any): void { var map = window.map; if (!map) return; if (window.sws) window.sws.forEach(function (p) { diff --git a/src/divide_segment.js b/src/divide_segment.js deleted file mode 100644 index 82ffb90..0000000 --- a/src/divide_segment.js +++ /dev/null @@ -1,39 +0,0 @@ -import SweepEvent from './sweep_event'; -import equals from './equals'; -import compareEvents from './compare_events'; - -/** - * @param {SweepEvent} se - * @param {Array.} p - * @param {Queue} queue - * @return {Queue} - */ -export default function divideSegment(se, p, queue) { - const r = new SweepEvent(p, false, se, se.isSubject); - const l = new SweepEvent(p, true, se.otherEvent, se.isSubject); - - /* eslint-disable no-console */ - if (equals(se.point, se.otherEvent.point)) { - console.warn('what is that, a collapsed segment?', se); - } - /* eslint-enable no-console */ - - r.contourId = l.contourId = se.contourId; - - // avoid a rounding error. The left event would be processed after the right event - if (compareEvents(l, se.otherEvent) > 0) { - se.otherEvent.left = true; - l.left = false; - } - - // avoid a rounding error. The left event would be processed after the right event - // if (compareEvents(se, r) > 0) {} - - se.otherEvent.otherEvent = l; - se.otherEvent = r; - - queue.push(l); - queue.push(r); - - return queue; -} diff --git a/src/divide_segment.ts b/src/divide_segment.ts new file mode 100644 index 0000000..08b3f6d --- /dev/null +++ b/src/divide_segment.ts @@ -0,0 +1,39 @@ +import SweepEvent from "./sweep_event"; +import equals from "./equals"; +import compareEvents from "./compare_events"; +import { Position } from "./types"; +import Queue from "tinyqueue"; + +export default function divideSegment( + se: SweepEvent, + p: Position, + queue: Queue +) { + const r = new SweepEvent(p, false, se, se.isSubject); + const l = new SweepEvent(p, true, se.otherEvent!, se.isSubject); + + /* eslint-disable no-console */ + if (equals(se.point, se.otherEvent!.point)) { + console.warn("what is that, a collapsed segment?", se); + } + /* eslint-enable no-console */ + + r.contourId = l.contourId = se.contourId; + + // avoid a rounding error. The left event would be processed after the right event + if (compareEvents(l, se.otherEvent!) > 0) { + se.otherEvent!.left = true; + l.left = false; + } + + // avoid a rounding error. The left event would be processed after the right event + // if (compareEvents(se, r) > 0) {} + + se.otherEvent!.otherEvent = l; + se.otherEvent = r; + + queue.push(l); + queue.push(r); + + return queue; +} diff --git a/src/edge_type.js b/src/edge_type.js deleted file mode 100644 index ab6f903..0000000 --- a/src/edge_type.js +++ /dev/null @@ -1,4 +0,0 @@ -export const NORMAL = 0; -export const NON_CONTRIBUTING = 1; -export const SAME_TRANSITION = 2; -export const DIFFERENT_TRANSITION = 3; diff --git a/src/edge_type.ts b/src/edge_type.ts new file mode 100644 index 0000000..137c5b5 --- /dev/null +++ b/src/edge_type.ts @@ -0,0 +1,6 @@ +export const NORMAL = 0 as const; +export const NON_CONTRIBUTING = 1 as const; +export const SAME_TRANSITION = 2 as const; +export const DIFFERENT_TRANSITION = 3 as const; + +export type EdgeType = typeof NORMAL | typeof NON_CONTRIBUTING | typeof SAME_TRANSITION | typeof DIFFERENT_TRANSITION; diff --git a/src/equals.js b/src/equals.ts similarity index 79% rename from src/equals.js rename to src/equals.ts index 2cca243..57f36ee 100644 --- a/src/equals.js +++ b/src/equals.ts @@ -1,4 +1,6 @@ -export default function equals(p1, p2) { +import { Position } from './types'; + +export default function equals(p1: Position, p2: Position): boolean { if (p1[0] === p2[0]) { if (p1[1] === p2[1]) { return true; diff --git a/src/externs.js b/src/externs.js deleted file mode 100644 index 4695558..0000000 --- a/src/externs.js +++ /dev/null @@ -1,78 +0,0 @@ -/* eslint-disable */ -/** - * Externs file for google closure compiler - */ -// this makes GCC play with browserify - -/* eslint-disable no-unused-vars */ - -/** - * @param {*=}o - * @param {*=}u - */ -window.require = function (o, u) {}; - -/** - * @type {Object} - */ -window.module = { - exports: {} -}; - -/** - * @api - * @static - * @param {Array>>} polygonA - * @param {Array>>} polygonB - * @return {Array>>|Null} - */ -window.martinez = function (polygonA, polygonB, operation) {}; - - -/** - * @enum {Number} - */ -window.martinez.operations = { - INTERSECTION: 0, - DIFFERENCE: 1, - UNION: 2, - XOR: 3 -}; - -/** - * @api - * @static - * @param {Array>>} polygonA - * @param {Array>>} polygonB - * @return {Array>>|Null} - */ -window.martinez.intersection = function (polygonA, polygonB) {}; - -/** - * @api - * @static - * @param {Array>>} polygonA - * @param {Array>>} polygonB - * @return {Array>>|Null} - */ -window.martinez.diff = function (polygonA, polygonB) {}; - -/** - * @api - * @static - * @param {Array>>} polygonA - * @param {Array>>} polygonB - * @return {Array>>|Null} - */ -window.martinez.union = function (polygonA, polygonB) {}; - -/** - * @api - * @static - * @param {Array>>} polygonA - * @param {Array>>} polygonB - * @return {Array>>|Null} - */ -window.martinez.intersection = function (polygonA, polygonB) {}; - -/* eslint-enable */ diff --git a/src/fill_queue.js b/src/fill_queue.ts similarity index 54% rename from src/fill_queue.js rename to src/fill_queue.ts index 9319722..c5cb4da 100644 --- a/src/fill_queue.js +++ b/src/fill_queue.ts @@ -1,21 +1,33 @@ -import Queue from 'tinyqueue'; -import SweepEvent from './sweep_event'; -import compareEvents from './compare_events'; -import { DIFFERENCE } from './operation'; +import Queue from "tinyqueue"; +import SweepEvent from "./sweep_event"; +import compareEvents from "./compare_events"; +import { DIFFERENCE } from "./operation"; +import { Position, Polygon, MultiPolygon, BBox } from "./types"; const max = Math.max; const min = Math.min; let contourId = 0; - -function processPolygon(contourOrHole, isSubject, depth, Q, bbox, isExteriorRing) { - let i, len, s1, s2, e1, e2; +function processPolygon( + contourOrHole: Position[], + isSubject: boolean, + depth: number, + Q: any, + bbox: BBox, + isExteriorRing: boolean +): void { + let i: number, + len: number, + s1: Position, + s2: Position, + e1: SweepEvent, + e2: SweepEvent; for (i = 0, len = contourOrHole.length - 1; i < len; i++) { s1 = contourOrHole[i]; s2 = contourOrHole[i + 1]; e1 = new SweepEvent(s1, false, undefined, isSubject); - e2 = new SweepEvent(s2, false, e1, isSubject); + e2 = new SweepEvent(s2, false, e1, isSubject); e1.otherEvent = e2; if (s1[0] === s2[0] && s1[1] === s2[1]) { @@ -33,7 +45,8 @@ function processPolygon(contourOrHole, isSubject, depth, Q, bbox, isExteriorRing e1.left = true; } - const x = s1[0], y = s1[1]; + const x = s1[0], + y = s1[1]; bbox[0] = min(bbox[0], x); bbox[1] = min(bbox[1], y); bbox[2] = max(bbox[2], x); @@ -46,17 +59,34 @@ function processPolygon(contourOrHole, isSubject, depth, Q, bbox, isExteriorRing } } - -export default function fillQueue(subject, clipping, sbbox, cbbox, operation) { - const eventQueue = new Queue(null, compareEvents); - let polygonSet, isExteriorRing, i, ii, j, jj; //, k, kk; +export default function fillQueue( + subject: MultiPolygon, + clipping: MultiPolygon, + sbbox: BBox, + cbbox: BBox, + operation: number +) { + const eventQueue = new Queue(undefined, compareEvents); + let polygonSet: Polygon, + isExteriorRing: boolean, + i: number, + ii: number, + j: number, + jj: number; //, k, kk; for (i = 0, ii = subject.length; i < ii; i++) { polygonSet = subject[i]; for (j = 0, jj = polygonSet.length; j < jj; j++) { isExteriorRing = j === 0; if (isExteriorRing) contourId++; - processPolygon(polygonSet[j], true, contourId, eventQueue, sbbox, isExteriorRing); + processPolygon( + polygonSet[j], + true, + contourId, + eventQueue, + sbbox, + isExteriorRing + ); } } @@ -66,7 +96,14 @@ export default function fillQueue(subject, clipping, sbbox, cbbox, operation) { isExteriorRing = j === 0; if (operation === DIFFERENCE) isExteriorRing = false; if (isExteriorRing) contourId++; - processPolygon(polygonSet[j], false, contourId, eventQueue, cbbox, isExteriorRing); + processPolygon( + polygonSet[j], + false, + contourId, + eventQueue, + cbbox, + isExteriorRing + ); } } diff --git a/src/index.js b/src/index.js deleted file mode 100644 index b3a3f69..0000000 --- a/src/index.js +++ /dev/null @@ -1,96 +0,0 @@ -import subdivideSegments from './subdivide_segments'; -import connectEdges from './connect_edges'; -import fillQueue from './fill_queue'; -import { - INTERSECTION, - DIFFERENCE, - UNION, - XOR -} from './operation'; - -const EMPTY = []; - - -function trivialOperation(subject, clipping, operation) { - let result = null; - if (subject.length * clipping.length === 0) { - if (operation === INTERSECTION) { - result = EMPTY; - } else if (operation === DIFFERENCE) { - result = subject; - } else if (operation === UNION || - operation === XOR) { - result = (subject.length === 0) ? clipping : subject; - } - } - return result; -} - - -function compareBBoxes(subject, clipping, sbbox, cbbox, operation) { - let result = null; - if (sbbox[0] > cbbox[2] || - cbbox[0] > sbbox[2] || - sbbox[1] > cbbox[3] || - cbbox[1] > sbbox[3]) { - if (operation === INTERSECTION) { - result = EMPTY; - } else if (operation === DIFFERENCE) { - result = subject; - } else if (operation === UNION || - operation === XOR) { - result = subject.concat(clipping); - } - } - return result; -} - - -export default function boolean(subject, clipping, operation) { - if (typeof subject[0][0][0] === 'number') { - subject = [subject]; - } - if (typeof clipping[0][0][0] === 'number') { - clipping = [clipping]; - } - let trivial = trivialOperation(subject, clipping, operation); - if (trivial) { - return trivial === EMPTY ? null : trivial; - } - const sbbox = [Infinity, Infinity, -Infinity, -Infinity]; - const cbbox = [Infinity, Infinity, -Infinity, -Infinity]; - - // console.time('fill queue'); - const eventQueue = fillQueue(subject, clipping, sbbox, cbbox, operation); - //console.timeEnd('fill queue'); - - trivial = compareBBoxes(subject, clipping, sbbox, cbbox, operation); - if (trivial) { - return trivial === EMPTY ? null : trivial; - } - // console.time('subdivide edges'); - const sortedEvents = subdivideSegments(eventQueue, subject, clipping, sbbox, cbbox, operation); - //console.timeEnd('subdivide edges'); - - // console.time('connect vertices'); - const contours = connectEdges(sortedEvents, operation); - //console.timeEnd('connect vertices'); - - // Convert contours to polygons - const polygons = []; - for (let i = 0; i < contours.length; i++) { - let contour = contours[i]; - if (contour.isExterior()) { - // The exterior ring goes first - let rings = [contour.points]; - // Followed by holes if any - for (let j = 0; j < contour.holeIds.length; j++) { - let holeId = contour.holeIds[j]; - rings.push(contours[holeId].points); - } - polygons.push(rings); - } - } - - return polygons; -} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..0d9639d --- /dev/null +++ b/src/index.ts @@ -0,0 +1,113 @@ +import subdivideSegments from "./subdivide_segments"; +import connectEdges from "./connect_edges"; +import fillQueue from "./fill_queue"; +import { INTERSECTION, DIFFERENCE, UNION, XOR } from "./operation"; +import { Geometry, Polygon, MultiPolygon, BBox } from "./types"; + +const EMPTY = []; + +function trivialOperation( + subject: MultiPolygon, + clipping: MultiPolygon, + operation: number +): MultiPolygon | null { + let result: MultiPolygon | null = null; + if (subject.length * clipping.length === 0) { + if (operation === INTERSECTION) { + result = EMPTY; + } else if (operation === DIFFERENCE) { + result = subject; + } else if (operation === UNION || operation === XOR) { + result = subject.length === 0 ? clipping : subject; + } + } + return result; +} + +function compareBBoxes( + subject: MultiPolygon, + clipping: MultiPolygon, + sbbox: BBox, + cbbox: BBox, + operation: number +): MultiPolygon | null { + let result: MultiPolygon | null = null; + if ( + sbbox[0] > cbbox[2] || + cbbox[0] > sbbox[2] || + sbbox[1] > cbbox[3] || + cbbox[1] > sbbox[3] + ) { + if (operation === INTERSECTION) { + result = EMPTY; + } else if (operation === DIFFERENCE) { + result = subject; + } else if (operation === UNION || operation === XOR) { + result = subject.concat(clipping); + } + } + return result; +} + +export default function boolean( + subject: Geometry, + clipping: Geometry, + operation: number +): MultiPolygon | null { + let subjectMP: MultiPolygon = subject as MultiPolygon; + let clippingMP: MultiPolygon = clipping as MultiPolygon; + + if (typeof subject[0][0][0] === "number") { + subjectMP = [subject as Polygon]; + } + if (typeof clipping[0][0][0] === "number") { + clippingMP = [clipping as Polygon]; + } + let trivial = trivialOperation(subjectMP, clippingMP, operation); + if (trivial) { + return trivial === EMPTY ? null : trivial; + } + const sbbox: BBox = [Infinity, Infinity, -Infinity, -Infinity]; + const cbbox: BBox = [Infinity, Infinity, -Infinity, -Infinity]; + + // console.time('fill queue'); + const eventQueue = fillQueue(subjectMP, clippingMP, sbbox, cbbox, operation); + //console.timeEnd('fill queue'); + + trivial = compareBBoxes(subjectMP, clippingMP, sbbox, cbbox, operation); + if (trivial) { + return trivial === EMPTY ? null : trivial; + } + // console.time('subdivide edges'); + const sortedEvents = subdivideSegments( + eventQueue, + subjectMP, + clippingMP, + sbbox, + cbbox, + operation + ); + //console.timeEnd('subdivide edges'); + + // console.time('connect vertices'); + const contours = connectEdges(sortedEvents); + //console.timeEnd('connect vertices'); + + // Convert contours to polygons + const polygons = []; + for (let i = 0; i < contours.length; i++) { + let contour = contours[i]; + if (contour.isExterior()) { + // The exterior ring goes first + let rings = [contour.points]; + // Followed by holes if any + for (let j = 0; j < contour.holeIds.length; j++) { + let holeId = contour.holeIds[j]; + rings.push(contours[holeId].points); + } + polygons.push(rings); + } + } + + return polygons; +} diff --git a/src/operation.js b/src/operation.ts similarity index 100% rename from src/operation.js rename to src/operation.ts diff --git a/src/possible_intersection.js b/src/possible_intersection.ts similarity index 61% rename from src/possible_intersection.js rename to src/possible_intersection.ts index 6889250..d746d9f 100644 --- a/src/possible_intersection.js +++ b/src/possible_intersection.ts @@ -1,36 +1,40 @@ -import divideSegment from './divide_segment'; -import intersection from './segment_intersection'; -import equals from './equals'; -import compareEvents from './compare_events'; +import divideSegment from "./divide_segment"; +import intersection from "./segment_intersection"; +import equals from "./equals"; +import compareEvents from "./compare_events"; +import SweepEvent from "./sweep_event"; import { NON_CONTRIBUTING, SAME_TRANSITION, - DIFFERENT_TRANSITION -} from './edge_type'; - -/** - * @param {SweepEvent} se1 - * @param {SweepEvent} se2 - * @param {Queue} queue - * @return {Number} - */ -export default function possibleIntersection (se1, se2, queue) { + DIFFERENT_TRANSITION, +} from "./edge_type"; +import Queue from "tinyqueue"; + +export default function possibleIntersection( + se1: SweepEvent, + se2: SweepEvent, + queue: Queue +): number { // that disallows self-intersecting polygons, // did cost us half a day, so I'll leave it // out of respect // if (se1.isSubject === se2.isSubject) return; const inter = intersection( - se1.point, se1.otherEvent.point, - se2.point, se2.otherEvent.point + se1.point, + se1.otherEvent!.point, + se2.point, + se2.otherEvent!.point ); const nintersections = inter ? inter.length : 0; if (nintersections === 0) return 0; // no intersection // the line segments intersect at an endpoint of both line segments - if ((nintersections === 1) && - (equals(se1.point, se2.point) || - equals(se1.otherEvent.point, se2.otherEvent.point))) { + if ( + nintersections === 1 && + (equals(se1.point, se2.point) || + equals(se1.otherEvent!.point, se2.otherEvent!.point)) + ) { return 0; } @@ -45,22 +49,27 @@ export default function possibleIntersection (se1, se2, queue) { // The line segments associated to se1 and se2 intersect if (nintersections === 1) { - // if the intersection point is not an endpoint of se1 - if (!equals(se1.point, inter[0]) && !equals(se1.otherEvent.point, inter[0])) { + if ( + !equals(se1.point, inter[0]) && + !equals(se1.otherEvent!.point, inter[0]) + ) { divideSegment(se1, inter[0], queue); } // if the intersection point is not an endpoint of se2 - if (!equals(se2.point, inter[0]) && !equals(se2.otherEvent.point, inter[0])) { + if ( + !equals(se2.point, inter[0]) && + !equals(se2.otherEvent!.point, inter[0]) + ) { divideSegment(se2, inter[0], queue); } return 1; } // The line segments associated to se1 and se2 overlap - const events = []; - let leftCoincide = false; + const events: SweepEvent[] = []; + let leftCoincide = false; let rightCoincide = false; if (equals(se1.point, se2.point)) { @@ -71,24 +80,23 @@ export default function possibleIntersection (se1, se2, queue) { events.push(se1, se2); } - if (equals(se1.otherEvent.point, se2.otherEvent.point)) { + if (equals(se1.otherEvent!.point, se2.otherEvent!.point)) { rightCoincide = true; - } else if (compareEvents(se1.otherEvent, se2.otherEvent) === 1) { - events.push(se2.otherEvent, se1.otherEvent); + } else if (compareEvents(se1.otherEvent!, se2.otherEvent!) === 1) { + events.push(se2.otherEvent!, se1.otherEvent!); } else { - events.push(se1.otherEvent, se2.otherEvent); + events.push(se1.otherEvent!, se2.otherEvent!); } if ((leftCoincide && rightCoincide) || leftCoincide) { // both line segments are equal or share the left endpoint se2.type = NON_CONTRIBUTING; - se1.type = (se2.inOut === se1.inOut) - ? SAME_TRANSITION : DIFFERENT_TRANSITION; + se1.type = se2.inOut === se1.inOut ? SAME_TRANSITION : DIFFERENT_TRANSITION; if (leftCoincide && !rightCoincide) { // honestly no idea, but changing events selection from [2, 1] // to [0, 1] fixes the overlapping self-intersecting polygons issue - divideSegment(events[1].otherEvent, events[0].point, queue); + divideSegment(events[1].otherEvent!, events[0].point, queue); } return 2; } @@ -100,7 +108,7 @@ export default function possibleIntersection (se1, se2, queue) { } // no line segment includes totally the other one - if (events[0] !== events[3].otherEvent) { + if (events[0] !== events[3].otherEvent!) { divideSegment(events[0], events[1].point, queue); divideSegment(events[1], events[2].point, queue); return 3; @@ -108,7 +116,7 @@ export default function possibleIntersection (se1, se2, queue) { // one line segment includes the other one divideSegment(events[0], events[1].point, queue); - divideSegment(events[3].otherEvent, events[2].point, queue); + divideSegment(events[3].otherEvent!, events[2].point, queue); return 3; } diff --git a/src/segment_intersection.js b/src/segment_intersection.ts similarity index 79% rename from src/segment_intersection.js rename to src/segment_intersection.ts index 1bcc718..5beb4ca 100644 --- a/src/segment_intersection.js +++ b/src/segment_intersection.ts @@ -1,27 +1,29 @@ +import { Position } from './types'; + //const EPS = 1e-9; /** * Finds the magnitude of the cross product of two vectors (if we pretend * they're in three dimensions) * - * @param {Object} a First vector - * @param {Object} b Second vector + * @param {Position} a First vector + * @param {Position} b Second vector * @private - * @returns {Number} The magnitude of the cross product + * @returns {number} The magnitude of the cross product */ -function crossProduct(a, b) { +function crossProduct(a: Position, b: Position): number { return (a[0] * b[1]) - (a[1] * b[0]); } /** * Finds the dot product of two vectors. * - * @param {Object} a First vector - * @param {Object} b Second vector + * @param {Position} a First vector + * @param {Position} b Second vector * @private - * @returns {Number} The dot product + * @returns {number} The dot product */ -function dotProduct(a, b) { +function dotProduct(a: Position, b: Position): number { return (a[0] * b[0]) + (a[1] * b[1]); } @@ -33,31 +35,31 @@ function dotProduct(a, b) { * http://www.cimec.org.ar/~ncalvo/Schneider_Eberly.pdf * Page 244. * - * @param {Array.} a1 point of first line - * @param {Array.} a2 point of first line - * @param {Array.} b1 point of second line - * @param {Array.} b2 point of second line - * @param {Boolean=} noEndpointTouch whether to skip single touchpoints + * @param {Position} a1 point of first line + * @param {Position} a2 point of first line + * @param {Position} b1 point of second line + * @param {Position} b2 point of second line + * @param {boolean=} noEndpointTouch whether to skip single touchpoints * (meaning connected segments) as * intersections - * @returns {Array.>|Null} If the lines intersect, the point of + * @returns {Position[]|null} If the lines intersect, the point of * intersection. If they overlap, the two end points of the overlapping segment. * Otherwise, null. */ -export default function (a1, a2, b1, b2, noEndpointTouch) { +export default function segmentIntersection(a1: Position, a2: Position, b1: Position, b2: Position, noEndpointTouch?: boolean): Position[] | null { // The algorithm expects our lines in the form P + sd, where P is a point, // s is on the interval [0, 1], and d is a vector. // We are passed two points. P can be the first point of each pair. The // vector, then, could be thought of as the distance (in x and y components) // from the first point to the second point. // So first, let's make our vectors: - const va = [a2[0] - a1[0], a2[1] - a1[1]]; - const vb = [b2[0] - b1[0], b2[1] - b1[1]]; + const va: Position = [a2[0] - a1[0], a2[1] - a1[1]]; + const vb: Position = [b2[0] - b1[0], b2[1] - b1[1]]; // We also define a function to convert back to regular point form: /* eslint-disable arrow-body-style */ - function toPoint(p, s, d) { + function toPoint(p: Position, s: number, d: Position): Position { return [ p[0] + s * d[0], p[1] + s * d[1] @@ -67,7 +69,7 @@ export default function (a1, a2, b1, b2, noEndpointTouch) { /* eslint-enable arrow-body-style */ // The rest is pretty much a straight port of the algorithm. - const e = [b1[0] - a1[0], b1[1] - a1[1]]; + const e: Position = [b1[0] - a1[0], b1[1] - a1[1]]; let kross = crossProduct(va, vb); let sqrKross = kross * kross; const sqrLenA = dotProduct(va, va); diff --git a/src/signed_area.js b/src/signed_area.ts similarity index 51% rename from src/signed_area.js rename to src/signed_area.ts index b738c38..d8e11af 100644 --- a/src/signed_area.js +++ b/src/signed_area.ts @@ -1,13 +1,14 @@ import {orient2d} from 'robust-predicates'; +import { Position } from './types'; /** * Signed area of the triangle (p0, p1, p2) - * @param {Array.} p0 - * @param {Array.} p1 - * @param {Array.} p2 - * @return {Number} + * @param {Position} p0 + * @param {Position} p1 + * @param {Position} p2 + * @return {number} */ -export default function signedArea(p0, p1, p2) { +export default function signedArea(p0: Position, p1: Position, p2: Position): number { const res = orient2d(p0[0], p0[1], p1[0], p1[1], p2[0], p2[1]); if (res > 0) return -1; if (res < 0) return 1; diff --git a/src/subdivide_segments.js b/src/subdivide_segments.ts similarity index 57% rename from src/subdivide_segments.js rename to src/subdivide_segments.ts index b4933cc..f152e8c 100644 --- a/src/subdivide_segments.js +++ b/src/subdivide_segments.ts @@ -1,37 +1,47 @@ -import Tree from 'splaytree'; -import computeFields from './compute_fields'; -import possibleIntersection from './possible_intersection'; -import compareSegments from './compare_segments'; -import { - INTERSECTION, - DIFFERENCE -} from './operation'; - - -export default function subdivide(eventQueue, subject, clipping, sbbox, cbbox, operation) { +import Tree, { Node } from "splaytree"; +import computeFields from "./compute_fields"; +import possibleIntersection from "./possible_intersection"; +import compareSegments from "./compare_segments"; +import SweepEvent from "./sweep_event"; +import { MultiPolygon, BBox } from "./types"; +import { INTERSECTION, DIFFERENCE } from "./operation"; +import Queue from "tinyqueue"; + +export default function subdivide( + eventQueue: Queue, + subject: MultiPolygon, + clipping: MultiPolygon, + sbbox: BBox, + cbbox: BBox, + operation: number +): SweepEvent[] { const sweepLine = new Tree(compareSegments); - const sortedEvents = []; + const sortedEvents: SweepEvent[] = []; const rightbound = Math.min(sbbox[2], cbbox[2]); - let prev, next, begin; + let prev: Node, + next: Node, + begin: Node; while (eventQueue.length !== 0) { - let event = eventQueue.pop(); + let event: SweepEvent = eventQueue.pop(); sortedEvents.push(event); // optimization by bboxes for intersection and difference goes here - if ((operation === INTERSECTION && event.point[0] > rightbound) || - (operation === DIFFERENCE && event.point[0] > sbbox[2])) { + if ( + (operation === INTERSECTION && event.point[0] > rightbound) || + (operation === DIFFERENCE && event.point[0] > sbbox[2]) + ) { break; } if (event.left) { - next = prev = sweepLine.insert(event); + next = prev = sweepLine.insert(event); begin = sweepLine.minNode(); if (prev !== begin) prev = sweepLine.prev(prev); - else prev = null; + else prev = null; next = sweepLine.next(next); @@ -49,11 +59,11 @@ export default function subdivide(eventQueue, subject, clipping, sbbox, cbbox, o if (possibleIntersection(prev.key, event, eventQueue) === 2) { let prevprev = prev; if (prevprev !== begin) prevprev = sweepLine.prev(prevprev); - else prevprev = null; + else prevprev = null; prevprevEvent = prevprev ? prevprev.key : null; computeFields(prevEvent, prevprevEvent, operation); - computeFields(event, prevEvent, operation); + computeFields(event, prevEvent, operation); } } } else { @@ -61,9 +71,8 @@ export default function subdivide(eventQueue, subject, clipping, sbbox, cbbox, o next = prev = sweepLine.find(event); if (prev && next) { - if (prev !== begin) prev = sweepLine.prev(prev); - else prev = null; + else prev = null; next = sweepLine.next(next); sweepLine.remove(event); diff --git a/src/sweep_event.js b/src/sweep_event.js deleted file mode 100644 index 1c2e991..0000000 --- a/src/sweep_event.js +++ /dev/null @@ -1,142 +0,0 @@ -import { NORMAL } from './edge_type'; - - -export default class SweepEvent { - - - /** - * Sweepline event - * - * @class {SweepEvent} - * @param {Array.} point - * @param {Boolean} left - * @param {SweepEvent=} otherEvent - * @param {Boolean} isSubject - * @param {Number} edgeType - */ - constructor (point, left, otherEvent, isSubject, edgeType) { - - /** - * Is left endpoint? - * @type {Boolean} - */ - this.left = left; - - /** - * @type {Array.} - */ - this.point = point; - - /** - * Other edge reference - * @type {SweepEvent} - */ - this.otherEvent = otherEvent; - - /** - * Belongs to source or clipping polygon - * @type {Boolean} - */ - this.isSubject = isSubject; - - /** - * Edge contribution type - * @type {Number} - */ - this.type = edgeType || NORMAL; - - - /** - * In-out transition for the sweepline crossing polygon - * @type {Boolean} - */ - this.inOut = false; - - - /** - * @type {Boolean} - */ - this.otherInOut = false; - - /** - * Previous event in result? - * @type {SweepEvent} - */ - this.prevInResult = null; - - /** - * Type of result transition (0 = not in result, +1 = out-in, -1, in-out) - * @type {Number} - */ - this.resultTransition = 0; - - // connection step - - /** - * @type {Number} - */ - this.otherPos = -1; - - /** - * @type {Number} - */ - this.outputContourId = -1; - - this.isExteriorRing = true; // TODO: Looks unused, remove? - } - - - /** - * @param {Array.} p - * @return {Boolean} - */ - isBelow (p) { - const p0 = this.point, p1 = this.otherEvent.point; - return this.left - ? (p0[0] - p[0]) * (p1[1] - p[1]) - (p1[0] - p[0]) * (p0[1] - p[1]) > 0 - // signedArea(this.point, this.otherEvent.point, p) > 0 : - : (p1[0] - p[0]) * (p0[1] - p[1]) - (p0[0] - p[0]) * (p1[1] - p[1]) > 0; - //signedArea(this.otherEvent.point, this.point, p) > 0; - } - - - /** - * @param {Array.} p - * @return {Boolean} - */ - isAbove (p) { - return !this.isBelow(p); - } - - - /** - * @return {Boolean} - */ - isVertical () { - return this.point[0] === this.otherEvent.point[0]; - } - - - /** - * Does event belong to result? - * @return {Boolean} - */ - get inResult() { - return this.resultTransition !== 0; - } - - - clone () { - const copy = new SweepEvent( - this.point, this.left, this.otherEvent, this.isSubject, this.type); - - copy.contourId = this.contourId; - copy.resultTransition = this.resultTransition; - copy.prevInResult = this.prevInResult; - copy.isExteriorRing = this.isExteriorRing; - copy.inOut = this.inOut; - copy.otherInOut = this.otherInOut; - - return copy; - } -} diff --git a/src/sweep_event.ts b/src/sweep_event.ts new file mode 100644 index 0000000..5231c74 --- /dev/null +++ b/src/sweep_event.ts @@ -0,0 +1,100 @@ +import { NORMAL, EdgeType } from './edge_type'; +import { Position } from './types'; + + +export default class SweepEvent { + // Property declarations + left: boolean; + point: Position; + otherEvent?: SweepEvent; + isSubject: boolean; + type: EdgeType; + inOut: boolean; + otherInOut: boolean; + prevInResult: SweepEvent | null; + resultTransition: number; + otherPos: number; + outputContourId: number; + isExteriorRing: boolean; + contourId?: number; + + /** + * Sweepline event + * + * @class {SweepEvent} + * @param {Position} point + * @param {boolean} left + * @param {SweepEvent=} otherEvent + * @param {boolean} isSubject + * @param {EdgeType} edgeType + */ + constructor (point: Position, left: boolean, otherEvent?: SweepEvent, isSubject?: boolean, edgeType?: EdgeType) { + this.left = left; + this.point = point; + this.otherEvent = otherEvent; + this.isSubject = isSubject ?? false; + this.type = edgeType || NORMAL; + this.inOut = false; + this.otherInOut = false; + this.prevInResult = null; + this.resultTransition = 0; + this.otherPos = -1; + this.outputContourId = -1; + this.isExteriorRing = true; + } + + + /** + * @param {Position} p + * @return {boolean} + */ + isBelow (p: Position): boolean { + const p0 = this.point, p1 = this.otherEvent!.point; + return this.left + ? (p0[0] - p[0]) * (p1[1] - p[1]) - (p1[0] - p[0]) * (p0[1] - p[1]) > 0 + // signedArea(this.point, this.otherEvent.point, p) > 0 : + : (p1[0] - p[0]) * (p0[1] - p[1]) - (p0[0] - p[0]) * (p1[1] - p[1]) > 0; + //signedArea(this.otherEvent.point, this.point, p) > 0; + } + + + /** + * @param {Position} p + * @return {boolean} + */ + isAbove (p: Position): boolean { + return !this.isBelow(p); + } + + + /** + * @return {boolean} + */ + isVertical (): boolean { + return this.point[0] === this.otherEvent!.point[0]; + } + + + /** + * Does event belong to result? + * @return {boolean} + */ + get inResult(): boolean { + return this.resultTransition !== 0; + } + + + clone (): SweepEvent { + const copy = new SweepEvent( + this.point, this.left, this.otherEvent, this.isSubject, this.type); + + copy.contourId = this.contourId; + copy.resultTransition = this.resultTransition; + copy.prevInResult = this.prevInResult; + copy.isExteriorRing = this.isExteriorRing; + copy.inOut = this.inOut; + copy.otherInOut = this.otherInOut; + + return copy; + } +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..3da5c9d --- /dev/null +++ b/src/types.ts @@ -0,0 +1,7 @@ +export type Position = [number, number]; +export type Ring = Position[]; +export type Polygon = Ring[]; +export type MultiPolygon = Polygon[]; +export type Geometry = Polygon | MultiPolygon; + +export type BBox = [number, number, number, number]; // [minX, minY, maxX, maxY] \ No newline at end of file diff --git a/test/compare_events.test.js b/test/compare_events.test.js deleted file mode 100644 index ef8066f..0000000 --- a/test/compare_events.test.js +++ /dev/null @@ -1,102 +0,0 @@ -import tap from 'tape'; -import Queue from 'tinyqueue'; -import sweepEventsComp from '../src/compare_events'; -import SweepEvent from '../src/sweep_event'; - -tap.test('queue', (main) => { - - main.test('queue should process lest(by x) sweep event first', (t) => { - const queue = new Queue(null, sweepEventsComp); - const e1 = {point: [0.0, 0.0]}; - const e2 = {point: [0.5, 0.5]}; - - queue.push(e1); - queue.push(e2); - - t.equals(e1, queue.pop()); - t.equals(e2, queue.pop()); - - t.end(); - }); - - main.test('queue should process lest(by y) sweep event first', (t) => { - const queue = new Queue(null, sweepEventsComp); - const e1 = {point: [0.0, 0.0]}; - const e2 = {point: [0.0, 0.5]}; - - queue.push(e1); - queue.push(e2); - - t.equals(e1, queue.pop()); - t.equals(e2, queue.pop()); - - t.end(); - }); - - - main.test('queue should pop least(by left prop) sweep event first', (t) => { - const queue = new Queue(null, sweepEventsComp); - const e1 = {point: [0.0, 0.0], left: true}; - const e2 = {point: [0.0, 0.0], left: false}; - - queue.push(e1); - queue.push(e2); - - t.equals(e2, queue.pop()); - t.equals(e1, queue.pop()); - - t.end(); - }); - - main.end(); -}); - -tap.test('sweep event comparison x coordinates', (t) => { - const e1 = {point: [0.0, 0.0]}; - const e2 = {point: [0.5, 0.5]}; - - t.equals(sweepEventsComp(e1, e2), -1); - t.equals(sweepEventsComp(e2, e1), 1); - - t.end(); -}); - -tap.test('sweep event comparison y coordinates', (t) => { - const e1 = {point: [0.0, 0.0]}; - const e2 = {point: [0.0, 0.5]}; - - t.equals(sweepEventsComp(e1, e2), -1); - t.equals(sweepEventsComp(e2, e1), 1); - - t.end(); -}); - -tap.test('sweep event comparison not left first', (t) => { - const e1 = {point: [0.0, 0.0], left: true}; - const e2 = {point: [0.0, 0.0], left: false}; - - t.equals(sweepEventsComp(e1, e2), 1); - t.equals(sweepEventsComp(e2, e1), -1); - - t.end(); -}); - -tap.test('sweep event comparison shared start point not collinear edges', (t) => { - const e1 = new SweepEvent([0.0, 0.0], true, new SweepEvent([1, 1], false)); - const e2 = new SweepEvent([0.0, 0.0], true, new SweepEvent([2, 3], false)); - - t.equals(sweepEventsComp(e1, e2), -1, 'lower is processed first'); - t.equals(sweepEventsComp(e2, e1), 1, 'higher is processed second'); - - t.end(); -}); - -tap.test('sweep event comparison collinear edges', (t) => { - const e1 = new SweepEvent([0.0, 0.0], true, new SweepEvent([1, 1], false), true); - const e2 = new SweepEvent([0.0, 0.0], true, new SweepEvent([2, 2], false), false); - - t.equals(sweepEventsComp(e1, e2), -1, 'clipping is processed first'); - t.equals(sweepEventsComp(e2, e1), 1, 'subject is processed second'); - - t.end(); -}); diff --git a/test/compare_events.test.ts b/test/compare_events.test.ts new file mode 100644 index 0000000..441c457 --- /dev/null +++ b/test/compare_events.test.ts @@ -0,0 +1,102 @@ +import { describe, it, expect } from "vitest"; +import Queue from "tinyqueue"; +import sweepEventsComp from "../src/compare_events"; +import SweepEvent from "../src/sweep_event"; + +describe("queue", () => { + it("should process least(by x) sweep event first", () => { + const queue = new Queue(undefined, sweepEventsComp); + const e1 = { point: [0.0, 0.0] }; + const e2 = { point: [0.5, 0.5] }; + + queue.push(e1); + queue.push(e2); + + expect(queue.pop()).toBe(e1); + expect(queue.pop()).toBe(e2); + }); + + it("should process least(by y) sweep event first", () => { + const queue = new Queue(undefined, sweepEventsComp); + const e1 = { point: [0.0, 0.0] }; + const e2 = { point: [0.0, 0.5] }; + + queue.push(e1); + queue.push(e2); + + expect(queue.pop()).toBe(e1); + expect(queue.pop()).toBe(e2); + }); + + it("should pop least(by left prop) sweep event first", () => { + const queue = new Queue(undefined, sweepEventsComp); + const e1 = { point: [0.0, 0.0], left: true }; + const e2 = { point: [0.0, 0.0], left: false }; + + queue.push(e1); + queue.push(e2); + + expect(queue.pop()).toBe(e2); + expect(queue.pop()).toBe(e1); + }); +}); + +describe("sweep event comparison x coordinates", () => { + it("should compare x coordinates correctly", () => { + const e1 = { point: [0.0, 0.0] }; + const e2 = { point: [0.5, 0.5] }; + + expect(sweepEventsComp(e1, e2)).toBe(-1); + expect(sweepEventsComp(e2, e1)).toBe(1); + }); +}); + +describe("sweep event comparison y coordinates", () => { + it("should compare y coordinates correctly", () => { + const e1 = { point: [0.0, 0.0] }; + const e2 = { point: [0.0, 0.5] }; + + expect(sweepEventsComp(e1, e2)).toBe(-1); + expect(sweepEventsComp(e2, e1)).toBe(1); + }); +}); + +describe("sweep event comparison not left first", () => { + it("should process not left events first", () => { + const e1 = { point: [0.0, 0.0], left: true }; + const e2 = { point: [0.0, 0.0], left: false }; + + expect(sweepEventsComp(e1, e2)).toBe(1); + expect(sweepEventsComp(e2, e1)).toBe(-1); + }); +}); + +describe("sweep event comparison shared start point not collinear edges", () => { + it("should process lower edge first", () => { + const e1 = new SweepEvent([0.0, 0.0], true, new SweepEvent([1, 1], false)); + const e2 = new SweepEvent([0.0, 0.0], true, new SweepEvent([2, 3], false)); + + expect(sweepEventsComp(e1, e2)).toBe(-1); + expect(sweepEventsComp(e2, e1)).toBe(1); + }); +}); + +describe("sweep event comparison collinear edges", () => { + it("should process clipping before subject", () => { + const e1 = new SweepEvent( + [0.0, 0.0], + true, + new SweepEvent([1, 1], false), + true + ); + const e2 = new SweepEvent( + [0.0, 0.0], + true, + new SweepEvent([2, 2], false), + false + ); + + expect(sweepEventsComp(e1, e2)).toBe(-1); + expect(sweepEventsComp(e2, e1)).toBe(1); + }); +}); diff --git a/test/compare_segments.test.js b/test/compare_segments.test.ts similarity index 50% rename from test/compare_segments.test.js rename to test/compare_segments.test.ts index 982be8c..5430575 100644 --- a/test/compare_segments.test.js +++ b/test/compare_segments.test.ts @@ -1,16 +1,15 @@ -'use strict'; -import tap from 'tape'; +import { describe, it, expect } from 'vitest'; import Tree from 'splaytree'; import compareSegments from '../src/compare_segments'; import compareEvents from '../src/compare_events'; import SweepEvent from '../src/sweep_event'; -tap.test('compare segments', (main) => { +describe('compare segments', () => { - main.test('not collinear', (secondary) => { + describe('not collinear', () => { - secondary.test('shared left point - right point first', (t) => { + it('should order by shared left point - right point first', () => { const tree = new Tree(compareSegments); const pt = [0.0, 0.0]; const se1 = new SweepEvent(pt, true, new SweepEvent([1, 1], false)); @@ -19,13 +18,11 @@ tap.test('compare segments', (main) => { tree.insert(se1); tree.insert(se2); - t.deepEqual(tree.maxNode().key.otherEvent.point, [2, 3]); - t.deepEqual(tree.minNode().key.otherEvent.point, [1, 1]); - - t.end(); + expect(tree.maxNode().key.otherEvent.point).toEqual([2, 3]); + expect(tree.minNode().key.otherEvent.point).toEqual([1, 1]); }); - secondary.test('different left point - right point y coord to sort', (t) => { + it('should sort by different left point - right point y coord', () => { const tree = new Tree(compareSegments); const se1 = new SweepEvent([0, 1], true, new SweepEvent([1, 1], false)); const se2 = new SweepEvent([0, 2], true, new SweepEvent([2, 3], false)); @@ -33,56 +30,46 @@ tap.test('compare segments', (main) => { tree.insert(se1); tree.insert(se2); - t.deepEqual(tree.minNode().key.otherEvent.point, [1, 1]); - t.deepEqual(tree.maxNode().key.otherEvent.point, [2, 3]); - - t.end(); + expect(tree.minNode().key.otherEvent.point).toEqual([1, 1]); + expect(tree.maxNode().key.otherEvent.point).toEqual([2, 3]); }); - secondary.test('events order in sweep line', (t) => { + it('should maintain events order in sweep line', () => { const se1 = new SweepEvent([0, 1], true, new SweepEvent([2, 1], false)); const se2 = new SweepEvent([-1, 0], true, new SweepEvent([2, 3], false)); const se3 = new SweepEvent([0, 1], true, new SweepEvent([3, 4], false)); const se4 = new SweepEvent([-1, 0], true, new SweepEvent([3, 1], false)); - t.equal(compareEvents(se1, se2), 1); - t.notOk(se2.isBelow(se1.point)); - t.ok(se2.isAbove(se1.point)); - - t.equal(compareSegments(se1, se2), -1, 'compare segments'); - t.equal(compareSegments(se2, se1), 1, 'compare segments inverted'); + expect(compareEvents(se1, se2)).toBe(1); + expect(se2.isBelow(se1.point)).toBeFalsy(); + expect(se2.isAbove(se1.point)).toBeTruthy(); - t.equal(compareEvents(se3, se4), 1); - t.notOk(se4.isAbove(se3.point)); + expect(compareSegments(se1, se2)).toBe(-1); + expect(compareSegments(se2, se1)).toBe(1); - t.end(); + expect(compareEvents(se3, se4)).toBe(1); + expect(se4.isAbove(se3.point)).toBeFalsy(); }); - secondary.test('first point is below', (t) => { + it('should handle when first point is below', () => { const se2 = new SweepEvent([0, 1], true, new SweepEvent([2, 1], false)); const se1 = new SweepEvent([-1, 0], true, new SweepEvent([2, 3], false)); - t.notOk(se1.isBelow(se2.point)); - t.equal(compareSegments(se1, se2), 1, 'compare segments'); - - t.end(); + expect(se1.isBelow(se2.point)).toBeFalsy(); + expect(compareSegments(se1, se2)).toBe(1); }); - - secondary.end(); }); - main.test('collinear segments', (t) => { + it('should handle collinear segments', () => { const se1 = new SweepEvent([1, 1], true, new SweepEvent([5, 1], false), true); const se2 = new SweepEvent([2, 1], true, new SweepEvent([3, 1], false), false); - t.notEqual(se1.isSubject, se2.isSubject); - t.equal(compareSegments(se1, se2), -1); - - t.end(); + expect(se1.isSubject).not.toBe(se2.isSubject); + expect(compareSegments(se1, se2)).toBe(-1); }); - main.test('collinear shared left point', (t) => { + it('should handle collinear shared left point', () => { const pt = [0, 1]; const se1 = new SweepEvent(pt, true, new SweepEvent([5, 1], false), false); @@ -91,31 +78,24 @@ tap.test('compare segments', (main) => { se1.contourId = 1; se2.contourId = 2; - t.equal(se1.isSubject, se2.isSubject); - t.equal(se1.point, se2.point); + expect(se1.isSubject).toBe(se2.isSubject); + expect(se1.point).toBe(se2.point); - t.equal(compareSegments(se1, se2), -1); + expect(compareSegments(se1, se2)).toBe(-1); se1.contourId = 2; se2.contourId = 1; - t.equal(compareSegments(se1, se2), +1); - - t.end(); + expect(compareSegments(se1, se2)).toBe(1); }); - - main.test('collinear same polygon different left points', (t) => { + it('should handle collinear same polygon different left points', () => { const se1 = new SweepEvent([1, 1], true, new SweepEvent([5, 1], false), true); const se2 = new SweepEvent([2, 1], true, new SweepEvent([3, 1], false), true); - t.equal(se1.isSubject, se2.isSubject); - t.notEqual(se1.point, se2.point); - t.equal(compareSegments(se1, se2), -1); - t.equal(compareSegments(se2, se1), 1); - - t.end(); + expect(se1.isSubject).toBe(se2.isSubject); + expect(se1.point).not.toBe(se2.point); + expect(compareSegments(se1, se2)).toBe(-1); + expect(compareSegments(se2, se1)).toBe(1); }); - - main.end(); -}); +}); \ No newline at end of file diff --git a/test/compute_fields.test.js b/test/compute_fields.test.js deleted file mode 100644 index 90cb119..0000000 --- a/test/compute_fields.test.js +++ /dev/null @@ -1,7 +0,0 @@ -import tap from 'tape'; -// var martinez = require('../src/'); -// var computeFields = martinez.computeFields; - -tap.test('compute fields', (t) => { - t.end(); -}); diff --git a/test/compute_fields.test.ts b/test/compute_fields.test.ts new file mode 100644 index 0000000..2af04fe --- /dev/null +++ b/test/compute_fields.test.ts @@ -0,0 +1,9 @@ +import { describe, it } from 'vitest'; +// var martinez = require('../src/'); +// var computeFields = martinez.computeFields; + +describe('compute fields', () => { + it('should handle compute fields operations', () => { + // Test placeholder - original test was empty + }); +}); \ No newline at end of file diff --git a/test/divide_segment.test.js b/test/divide_segment.test.js deleted file mode 100644 index d7a75d1..0000000 --- a/test/divide_segment.test.js +++ /dev/null @@ -1,247 +0,0 @@ -import tap from 'tape'; -import path from 'path'; -import Queue from 'tinyqueue'; -import load from 'load-json-file'; -import martinez from '../'; -import SweepEvent from '../src/sweep_event'; -import compareEvents from '../src/compare_events'; -import intersection from '../src/segment_intersection'; -import equals from '../src/equals'; -import fillQueue from '../src/fill_queue'; -import divideSegment from '../src/divide_segment'; -import subdivideSegments from '../src/subdivide_segments'; -import possibleIntersection from '../src/possible_intersection'; -import Tree from 'splaytree'; -import compareSegments from '../src/compare_segments'; - -// GeoJSON Data -const shapes = load.sync(path.join(__dirname, 'fixtures', 'two_shapes.geojson')); - - - -const subject = shapes.features[0]; -const clipping = shapes.features[1]; - -tap.test('divide segments', (main) => { - - main.test('divide 2 segments', (t) => { - const se1 = new SweepEvent([0, 0], true, new SweepEvent([5, 5], false), true); - const se2 = new SweepEvent([0, 5], true, new SweepEvent([5, 0], false), false); - const q = new Queue(null, compareEvents); - - q.push(se1); - q.push(se2); - - const iter = intersection( - se1.point, se1.otherEvent.point, - se2.point, se2.otherEvent.point - ); - - - divideSegment(se1, iter[0], q); - divideSegment(se2, iter[0], q); - - t.equals(q.length, 6, 'subdivided in 4 segments by intersection point'); - - t.end(); - }); - - main.test('possible intersections', (t) => { - - const s = subject.geometry.coordinates; - const c = clipping.geometry.coordinates; - - const q = new Queue(null, compareEvents); - - const se1 = new SweepEvent(s[0][3], true, new SweepEvent(s[0][2], false), true); - const se2 = new SweepEvent(c[0][0], true, new SweepEvent(c[0][1], false), false); - - // console.log(se1.point, se1.left, se1.otherEvent.point, se1.otherEvent.left); - // console.log(se2.point, se2.left, se2.otherEvent.point, se2.otherEvent.left); - - t.equals(possibleIntersection(se1, se2, q), 1); - t.equals(q.length, 4); - - let e; - - e = q.pop(); - t.deepEqual(e.point, [100.79403384562251, 233.41363754101192]); - t.deepEqual(e.otherEvent.point, [56, 181], '1'); - - e = q.pop(); - t.deepEqual(e.point, [100.79403384562251, 233.41363754101192]); - t.deepEqual(e.otherEvent.point, [16, 282], '2'); - - e = q.pop(); - t.deepEqual(e.point, [100.79403384562251, 233.41363754101192]); - t.deepEqual(e.otherEvent.point, [153, 203.5], '3'); - - e = q.pop(); - t.deepEqual(e.point, [100.79403384562251, 233.41363754101192]); - t.deepEqual(e.otherEvent.point, [153, 294.5], '4'); - - t.end(); - }); - - main.test('possible intersections on 2 polygons', (t) => { - const s = [subject.geometry.coordinates]; - const c = [clipping.geometry.coordinates]; - - const bbox = [Infinity, Infinity, -Infinity, -Infinity]; - const q = fillQueue(s, c, bbox, bbox); - const p0 = [16, 282]; - const p1 = [298, 359]; - const p2 = [156, 203.5]; - - const te = new SweepEvent(p0, true, null, true); - const te2 = new SweepEvent(p1, false, te, false); - te.otherEvent = te2; - - const te3 = new SweepEvent(p0, true, null, true); - const te4 = new SweepEvent(p2, true, te3, false); - te3.otherEvent = te4; - - const tr = new Tree(compareSegments); - - t.ok(tr.insert(te), 'insert'); - t.ok(tr.insert(te3), 'insert'); - - t.equals(tr.find(te).key, te); - t.equals(tr.find(te3).key, te3); - - t.equals(compareSegments(te, te3), 1); - t.equals(compareSegments(te3, te), -1); - - const segments = subdivideSegments(q, s, c, bbox, bbox, 0); - const leftSegments = []; - for (let i = 0; i < segments.length; i++) { - if (segments[i].left) { - leftSegments.push(segments[i]); - } - } - - t.equals(leftSegments.length, 11); - - const E = [16, 282]; - const I = [100.79403384562252, 233.41363754101192]; - const G = [298, 359]; - const C = [153, 294.5]; - const J = [203.36313843035356, 257.5101243166895]; - const F = [153, 203.5]; - const D = [56, 181]; - const A = [108.5, 120]; - const B = [241.5, 229.5]; - - const intervals = { - 'EI': { - l: E, r: I, - inOut: false, - otherInOut: true, - inResult: false, - prevInResult: null - }, - 'IF': { - l: I, r: F, - inOut: false, - otherInOut: false, - inResult: true, - prevInResult: null - }, - 'FJ': { - l: F, r: J, - inOut: false, - otherInOut: false, - inResult: true, - prevInResult: null - }, - 'JG': { - l: J, r: G, - inOut: false, - otherInOut: true, - inResult: false, - prevInResult: null - }, - 'EG': { - l: E, r: G, - inOut: true, - otherInOut: true, - inResult: false, - prevInResult: null - }, - 'DA': { - l: D, r: A, - inOut: false, - otherInOut: true, - inResult: false, - prevInResult: null - }, - 'AB': { - l: A, r: B, - inOut: false, - otherInOut: true, - inResult: false, - prevInResult: null - }, - 'JB': { - l: J, r: B, - inOut: true, - otherInOut: true, - inResult: false, - prevInResult: null - }, - - 'CJ': { - l: C, r: J, - inOut: true, - otherInOut: false, - inResult: true, - prevInResult: { - l: F, r: J, - prevInResult: null - } - }, - 'IC': { - l: I, r: C, - inOut: true, - otherInOut: false, - inResult: true, - prevInResult: { - l: I, r: F, - prevInResult: null - }}, - - 'DI': { - l: D, r: I, - inOut: true, - otherInOut: true, - inResult: false, - prevInResult: null - } - }; - - function checkContain(interval) { - const data = intervals[interval]; - for (let x = 0; x < leftSegments.length; x++) { - const seg = leftSegments[x]; - if (equals(seg.point, data.l) && - equals(seg.otherEvent.point, data.r) && - seg.inOut === data.inOut && - seg.otherInOut === data.otherInOut && - seg.inResult === data.inResult && - ((seg.prevInResult === null && data.prevInResult === null) || - (equals(seg.prevInResult.point, data.prevInResult.l) && - equals(seg.prevInResult.otherEvent.point, data.prevInResult.r)))) { - t.pass(interval); - return; - } - } - t.fail(interval); - } - - Object.keys(intervals).forEach((key) => checkContain(key)); - - t.end(); - }); - - main.end(); -}); diff --git a/test/divide_segment.test.ts b/test/divide_segment.test.ts new file mode 100644 index 0000000..8720b00 --- /dev/null +++ b/test/divide_segment.test.ts @@ -0,0 +1,276 @@ +import { describe, it, expect } from "vitest"; +import { readFileSync } from "fs"; +import { join } from "path"; +import Queue from "tinyqueue"; +import SweepEvent from "../src/sweep_event"; +import compareEvents from "../src/compare_events"; +import intersection from "../src/segment_intersection"; +import equals from "../src/equals"; +import fillQueue from "../src/fill_queue"; +import divideSegment from "../src/divide_segment"; +import subdivideSegments from "../src/subdivide_segments"; +import possibleIntersection from "../src/possible_intersection"; +import Tree from "splaytree"; +import compareSegments from "../src/compare_segments"; +import { INTERSECTION } from "../src/operation"; + +// GeoJSON Data +const shapes = JSON.parse( + readFileSync(join(__dirname, "fixtures", "two_shapes.geojson"), "utf-8") +); + +const subject = shapes.features[0]; +const clipping = shapes.features[1]; + +describe("divide segments", () => { + it("should divide 2 segments", () => { + const se1 = new SweepEvent( + [0, 0], + true, + new SweepEvent([5, 5], false), + true + ); + const se2 = new SweepEvent( + [0, 5], + true, + new SweepEvent([5, 0], false), + false + ); + const q = new Queue(undefined, compareEvents); + + q.push(se1); + q.push(se2); + + const iter = intersection( + se1.point, + se1.otherEvent.point, + se2.point, + se2.otherEvent.point + ); + + divideSegment(se1, iter[0], q); + divideSegment(se2, iter[0], q); + + expect(q.length).toBe(6); + }); + + it("should handle possible intersections", () => { + const s = subject.geometry.coordinates; + const c = clipping.geometry.coordinates; + + const q = new Queue(undefined, compareEvents); + + const se1 = new SweepEvent( + s[0][3], + true, + new SweepEvent(s[0][2], false), + true + ); + const se2 = new SweepEvent( + c[0][0], + true, + new SweepEvent(c[0][1], false), + false + ); + + expect(possibleIntersection(se1, se2, q)).toBe(1); + expect(q.length).toBe(4); + + let e; + + e = q.pop(); + expect(e.point).toEqual([100.79403384562251, 233.41363754101192]); + expect(e.otherEvent.point).toEqual([56, 181]); + + e = q.pop(); + expect(e.point).toEqual([100.79403384562251, 233.41363754101192]); + expect(e.otherEvent.point).toEqual([16, 282]); + + e = q.pop(); + expect(e.point).toEqual([100.79403384562251, 233.41363754101192]); + expect(e.otherEvent.point).toEqual([153, 203.5]); + + e = q.pop(); + expect(e.point).toEqual([100.79403384562251, 233.41363754101192]); + expect(e.otherEvent.point).toEqual([153, 294.5]); + }); + + it("should handle possible intersections on 2 polygons", () => { + const s = [subject.geometry.coordinates]; + const c = [clipping.geometry.coordinates]; + + const bbox: [number, number, number, number] = [ + Infinity, + Infinity, + -Infinity, + -Infinity, + ]; + const q = fillQueue(s, c, bbox, bbox, INTERSECTION); + const p0 = [16, 282]; + const p1 = [298, 359]; + const p2 = [156, 203.5]; + + const te = new SweepEvent(p0, true, null, true); + const te2 = new SweepEvent(p1, false, te, false); + te.otherEvent = te2; + + const te3 = new SweepEvent(p0, true, null, true); + const te4 = new SweepEvent(p2, true, te3, false); + te3.otherEvent = te4; + + const tr = new Tree(compareSegments); + + expect(tr.insert(te)).toBeTruthy(); + expect(tr.insert(te3)).toBeTruthy(); + + expect(tr.find(te).key).toBe(te); + expect(tr.find(te3).key).toBe(te3); + + expect(compareSegments(te, te3)).toBe(1); + expect(compareSegments(te3, te)).toBe(-1); + + const segments = subdivideSegments(q, s, c, bbox, bbox, 0); + const leftSegments = []; + for (let i = 0; i < segments.length; i++) { + if (segments[i].left) { + leftSegments.push(segments[i]); + } + } + + expect(leftSegments.length).toBe(11); + + const E = [16, 282]; + const I = [100.79403384562252, 233.41363754101192]; + const G = [298, 359]; + const C = [153, 294.5]; + const J = [203.36313843035356, 257.5101243166895]; + const F = [153, 203.5]; + const D = [56, 181]; + const A = [108.5, 120]; + const B = [241.5, 229.5]; + + const intervals = { + EI: { + l: E, + r: I, + inOut: false, + otherInOut: true, + inResult: false, + prevInResult: null, + }, + IF: { + l: I, + r: F, + inOut: false, + otherInOut: false, + inResult: true, + prevInResult: null, + }, + FJ: { + l: F, + r: J, + inOut: false, + otherInOut: false, + inResult: true, + prevInResult: null, + }, + JG: { + l: J, + r: G, + inOut: false, + otherInOut: true, + inResult: false, + prevInResult: null, + }, + EG: { + l: E, + r: G, + inOut: true, + otherInOut: true, + inResult: false, + prevInResult: null, + }, + DA: { + l: D, + r: A, + inOut: false, + otherInOut: true, + inResult: false, + prevInResult: null, + }, + AB: { + l: A, + r: B, + inOut: false, + otherInOut: true, + inResult: false, + prevInResult: null, + }, + JB: { + l: J, + r: B, + inOut: true, + otherInOut: true, + inResult: false, + prevInResult: null, + }, + + CJ: { + l: C, + r: J, + inOut: true, + otherInOut: false, + inResult: true, + prevInResult: { + l: F, + r: J, + prevInResult: null, + }, + }, + IC: { + l: I, + r: C, + inOut: true, + otherInOut: false, + inResult: true, + prevInResult: { + l: I, + r: F, + prevInResult: null, + }, + }, + + DI: { + l: D, + r: I, + inOut: true, + otherInOut: true, + inResult: false, + prevInResult: null, + }, + }; + + function checkContain(interval: string) { + const data = intervals[interval]; + for (let x = 0; x < leftSegments.length; x++) { + const seg = leftSegments[x]; + if ( + equals(seg.point, data.l) && + equals(seg.otherEvent.point, data.r) && + seg.inOut === data.inOut && + seg.otherInOut === data.otherInOut && + seg.inResult === data.inResult && + ((seg.prevInResult === null && data.prevInResult === null) || + (equals(seg.prevInResult.point, data.prevInResult.l) && + equals(seg.prevInResult.otherEvent.point, data.prevInResult.r))) + ) { + expect(true).toBeTruthy(); // Pass test for interval + return; + } + } + expect(false).toBeTruthy(); // Fail test for interval + } + + Object.keys(intervals).forEach((key) => checkContain(key)); + }); +}); diff --git a/test/featureTypes.test.js b/test/featureTypes.test.js deleted file mode 100644 index 0797f45..0000000 --- a/test/featureTypes.test.js +++ /dev/null @@ -1,56 +0,0 @@ -import tap from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import * as martinez from '../index'; - -const clipping = load.sync(path.join(__dirname, 'featureTypes', 'clippingPoly.geojson')); -const outDir = path.join(__dirname, 'featureTypes', 'out'); - -const testScenarios = [ - { - testName: 'polyToClipping', - subjectPoly: 'poly', - }, - { - testName: 'polyWithHoleToClipping', - subjectPoly: 'polyWithHole', - }, - { - testName: 'multiPolyToClipping', - subjectPoly: 'multiPoly', - }, - { - testName: 'multiPolyWithHoleToClipping', - subjectPoly: 'multiPolyWithHole', - } -]; - -testScenarios.forEach((ts) => { - const subject = load.sync(path.join(__dirname, 'featureTypes', ts.subjectPoly + '.geojson')); - tap.test(ts.testName, (t) => { - - const expectedIntResult = load.sync(path.join(outDir, 'intersection', t.name + '.geojson')) - if (expectedIntResult.geometry.type === 'Polygon') expectedIntResult.geometry.coordinates = [expectedIntResult.geometry.coordinates] - const intResult = martinez.intersection(subject.geometry.coordinates, clipping.geometry.coordinates); - t.same(intResult, expectedIntResult.geometry.coordinates, ts.testName + ' - Intersect'); - - const expectedXorResult = load.sync(path.join(outDir, 'xor', t.name + '.geojson')) - if (expectedXorResult.geometry.type === 'Polygon') expectedXorResult.geometry.coordinates = [expectedXorResult.geometry.coordinates] - const xorResult = martinez.xor(subject.geometry.coordinates, clipping.geometry.coordinates); - t.same(xorResult, expectedXorResult.geometry.coordinates, ts.testName + ' - XOR'); - - const expectedDiffResult = load.sync(path.join(outDir, 'difference', t.name + '.geojson')) - if (expectedDiffResult.geometry.type === 'Polygon') expectedDiffResult.geometry.coordinates = [expectedDiffResult.geometry.coordinates] - const diffResult = martinez.diff(subject.geometry.coordinates, clipping.geometry.coordinates); - t.same(diffResult, expectedDiffResult.geometry.coordinates, ts.testName + ' - Difference'); - - const expectedUnionResult = load.sync(path.join(outDir, 'union', t.name + '.geojson')) - if (expectedUnionResult.geometry.type === 'Polygon') expectedUnionResult.geometry.coordinates = [expectedUnionResult.geometry.coordinates] - const unionResult = martinez.union(subject.geometry.coordinates, clipping.geometry.coordinates); - t.same(unionResult, expectedUnionResult.geometry.coordinates, ts.testName + ' - Union'); - - t.end(); - }); - -}); - diff --git a/test/featureTypes.test.ts b/test/featureTypes.test.ts new file mode 100644 index 0000000..0ed8f55 --- /dev/null +++ b/test/featureTypes.test.ts @@ -0,0 +1,62 @@ +import { describe, it, expect } from 'vitest'; +import { readFileSync } from 'fs'; +import { join } from 'path'; +import * as martinez from '../index'; + +const clipping = JSON.parse(readFileSync(join(__dirname, 'featureTypes', 'clippingPoly.geojson'), 'utf-8')); +const outDir = join(__dirname, 'featureTypes', 'out'); + +const testScenarios = [ + { + testName: 'polyToClipping', + subjectPoly: 'poly', + }, + { + testName: 'polyWithHoleToClipping', + subjectPoly: 'polyWithHole', + }, + { + testName: 'multiPolyToClipping', + subjectPoly: 'multiPoly', + }, + { + testName: 'multiPolyWithHoleToClipping', + subjectPoly: 'multiPolyWithHole', + } +]; + +describe('Feature Types Tests', () => { + testScenarios.forEach((ts) => { + const subject = JSON.parse(readFileSync(join(__dirname, 'featureTypes', ts.subjectPoly + '.geojson'), 'utf-8')); + + describe(ts.testName, () => { + it('should perform intersection operation correctly', () => { + const expectedIntResult = JSON.parse(readFileSync(join(outDir, 'intersection', ts.testName + '.geojson'), 'utf-8')); + if (expectedIntResult.geometry.type === 'Polygon') expectedIntResult.geometry.coordinates = [expectedIntResult.geometry.coordinates]; + const intResult = martinez.intersection(subject.geometry.coordinates, clipping.geometry.coordinates); + expect(intResult).toEqual(expectedIntResult.geometry.coordinates); + }); + + it('should perform XOR operation correctly', () => { + const expectedXorResult = JSON.parse(readFileSync(join(outDir, 'xor', ts.testName + '.geojson'), 'utf-8')); + if (expectedXorResult.geometry.type === 'Polygon') expectedXorResult.geometry.coordinates = [expectedXorResult.geometry.coordinates]; + const xorResult = martinez.xor(subject.geometry.coordinates, clipping.geometry.coordinates); + expect(xorResult).toEqual(expectedXorResult.geometry.coordinates); + }); + + it('should perform difference operation correctly', () => { + const expectedDiffResult = JSON.parse(readFileSync(join(outDir, 'difference', ts.testName + '.geojson'), 'utf-8')); + if (expectedDiffResult.geometry.type === 'Polygon') expectedDiffResult.geometry.coordinates = [expectedDiffResult.geometry.coordinates]; + const diffResult = martinez.diff(subject.geometry.coordinates, clipping.geometry.coordinates); + expect(diffResult).toEqual(expectedDiffResult.geometry.coordinates); + }); + + it('should perform union operation correctly', () => { + const expectedUnionResult = JSON.parse(readFileSync(join(outDir, 'union', ts.testName + '.geojson'), 'utf-8')); + if (expectedUnionResult.geometry.type === 'Polygon') expectedUnionResult.geometry.coordinates = [expectedUnionResult.geometry.coordinates]; + const unionResult = martinez.union(subject.geometry.coordinates, clipping.geometry.coordinates); + expect(unionResult).toEqual(expectedUnionResult.geometry.coordinates); + }); + }); + }); +}); \ No newline at end of file diff --git a/test/genericTestCases.test.js b/test/genericTestCases.test.js deleted file mode 100644 index ceae7f8..0000000 --- a/test/genericTestCases.test.js +++ /dev/null @@ -1,84 +0,0 @@ -import tap from 'tape'; -import path from 'path'; -import glob from 'glob'; -import load from 'load-json-file'; -import fs from 'fs'; -import stringify from 'json-stringify-pretty-compact'; -import * as martinez from '../index'; - - -function extractExpectedResults(features) { - return features.map(feature => { - let mode = feature.properties.operation; - var op; - switch (mode) { - case "union": - op = martinez.union; - break; - case "intersection": - op = martinez.intersection; - break; - case "xor": - op = martinez.xor; - break; - case "diff": - op = martinez.diff; - break; - case "diff_ba": - op = (a, b) => martinez.diff(b, a); - break; - } - if (op == null) { - throw `Invalid mode: ${mode}`; - } - return { - op: op, - coordinates: feature.geometry.coordinates, - }; - }); -} - - -const caseDir = path.join(__dirname, 'genericTestCases'); -const testCases = glob.sync(path.join(caseDir, '*.geojson')); -if (testCases.length === 0) { - throw 'No test cases found, this must not happen'; -} - -testCases.forEach((testCaseFile) => { - let testName = 'Generic test case: ' + path.basename(testCaseFile); - tap.test(testName, (t) => { - - const data = load.sync(testCaseFile); - if (data.features.length < 2) { - throw `Test case file must contain at least two features, but ${testCaseFile} doesn't.`; - } - - let p1Geometry = data.features[0].geometry; - let p2Geometry = data.features[1].geometry; - - let p1 = p1Geometry.type === 'Polygon' ? [p1Geometry.coordinates] : p1Geometry.coordinates; - let p2 = p2Geometry.type === 'Polygon' ? [p2Geometry.coordinates] : p2Geometry.coordinates; - - let expectedResults = extractExpectedResults(data.features.slice(2)); - - let featureIndex = 2; - for (const expectedResult of expectedResults) { - const result = expectedResult.op(p1, p2); - t.same(result, expectedResult.coordinates); - - // Update output data for re-generation mode - data.features[featureIndex].geometry.type = 'MultiPolygon'; - data.features[featureIndex].geometry.coordinates = result; - featureIndex += 1; - } - - if (process.env.REGEN) { - fs.writeFileSync(testCaseFile, stringify(data)); - } - - t.end(); - }); - -}); - diff --git a/test/genericTestCases.test.ts b/test/genericTestCases.test.ts new file mode 100644 index 0000000..28b443c --- /dev/null +++ b/test/genericTestCases.test.ts @@ -0,0 +1,81 @@ +import { describe, it, expect } from 'vitest'; +import { readFileSync, writeFileSync } from 'fs'; +import { join, basename } from 'path'; +import { globSync } from 'glob'; +import stringify from 'json-stringify-pretty-compact'; +import * as martinez from '../index'; + +function extractExpectedResults(features: any[]) { + return features.map(feature => { + let mode = feature.properties.operation; + let op: any; + switch (mode) { + case "union": + op = martinez.union; + break; + case "intersection": + op = martinez.intersection; + break; + case "xor": + op = martinez.xor; + break; + case "diff": + op = martinez.diff; + break; + case "diff_ba": + op = (a: any, b: any) => martinez.diff(b, a); + break; + } + if (op == null) { + throw `Invalid mode: ${mode}`; + } + return { + op: op, + coordinates: feature.geometry.coordinates, + }; + }); +} + +const caseDir = join(__dirname, 'genericTestCases'); +const testCases = globSync(join(caseDir, '*.geojson')); +if (testCases.length === 0) { + throw new Error('No test cases found, this must not happen'); +} + +describe('Generic Test Cases', () => { + testCases.forEach((testCaseFile) => { + let testName = 'Generic test case: ' + basename(testCaseFile); + + describe(testName, () => { + it('should execute test case operations correctly', () => { + const data = JSON.parse(readFileSync(testCaseFile, 'utf-8')); + if (data.features.length < 2) { + throw `Test case file must contain at least two features, but ${testCaseFile} doesn't.`; + } + + let p1Geometry = data.features[0].geometry; + let p2Geometry = data.features[1].geometry; + + let p1 = p1Geometry.type === 'Polygon' ? [p1Geometry.coordinates] : p1Geometry.coordinates; + let p2 = p2Geometry.type === 'Polygon' ? [p2Geometry.coordinates] : p2Geometry.coordinates; + + let expectedResults = extractExpectedResults(data.features.slice(2)); + + let featureIndex = 2; + for (const expectedResult of expectedResults) { + const result = expectedResult.op(p1, p2); + expect(result).toEqual(expectedResult.coordinates); + + // Update output data for re-generation mode + data.features[featureIndex].geometry.type = 'MultiPolygon'; + data.features[featureIndex].geometry.coordinates = result; + featureIndex += 1; + } + + if (process.env.REGEN) { + writeFileSync(testCaseFile, stringify(data)); + } + }); + }); + }); +}); \ No newline at end of file diff --git a/test/genericTestCases/basic1_poly.geojson b/test/genericTestCases/basic1_poly.geojson new file mode 100644 index 0000000..740e8b4 --- /dev/null +++ b/test/genericTestCases/basic1_poly.geojson @@ -0,0 +1,136 @@ +{ + "features": [ + { + "geometry": { + "coordinates": [ + [ + [0, 0], + [0, 1], + [1, 1], + [1, 0], + [0, 0] + ] + ], + "type": "Polygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [0.25, 0.25], + [2.75, 0.25], + [2.75, 2.75], + [0.25, 2.75], + [0.25, 0.25] + ] + ], + "type": "Polygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [0.25, 0.25], + [1, 0.25], + [1, 1], + [0.25, 1], + [0.25, 0.25] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "intersection" + }, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [0, 0], + [1, 0], + [1, 0.25], + [2.75, 0.25], + [2.75, 2.75], + [0.25, 2.75], + [0.25, 1], + [0, 1], + [0, 0] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "union" + }, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [0, 0], + [1, 0], + [1, 0.25], + [0.25, 0.25], + [0.25, 1], + [0, 1], + [0, 0] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "diff" + }, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [0, 0], + [1, 0], + [1, 0.25], + [0.25, 0.25], + [0.25, 1], + [0, 1], + [0, 0] + ] + ], + [ + [ + [0.25, 1], + [1, 1], + [1, 0.25], + [2.75, 0.25], + [2.75, 2.75], + [0.25, 2.75], + [0.25, 1] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "xor" + }, + "type": "Feature" + } + ], + "type": "FeatureCollection" +} diff --git a/test/genericTestCases/basic3_multi_poly.geojson b/test/genericTestCases/basic3_multi_poly.geojson new file mode 100644 index 0000000..1f57025 --- /dev/null +++ b/test/genericTestCases/basic3_multi_poly.geojson @@ -0,0 +1,184 @@ +{ + "features": [ + { + "geometry": { + "coordinates": [ + [ + [ + [0, 0], + [1, 0], + [1, 1], + [0, 1], + [0, 0] + ] + ], + [ + [ + [2, 2], + [3, 2], + [3, 3], + [2, 3], + [2, 2] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [0.25, 0.25], + [2.75, 0.25], + [2.75, 2.75], + [0.25, 2.75], + [0.25, 0.25] + ] + ], + "type": "Polygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [0.25, 0.25], + [1, 0.25], + [1, 1], + [0.25, 1], + [0.25, 0.25] + ] + ], + [ + [ + [2, 2], + [2.75, 2], + [2.75, 2.75], + [2, 2.75], + [2, 2] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "intersection" + }, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [0, 0], + [1, 0], + [1, 0.25], + [2.75, 0.25], + [2.75, 2], + [3, 2], + [3, 3], + [2, 3], + [2, 2.75], + [0.25, 2.75], + [0.25, 1], + [0, 1], + [0, 0] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "union" + }, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [0, 0], + [1, 0], + [1, 0.25], + [0.25, 0.25], + [0.25, 1], + [0, 1], + [0, 0] + ] + ], + [ + [ + [2, 2.75], + [2.75, 2.75], + [2.75, 2], + [3, 2], + [3, 3], + [2, 3], + [2, 2.75] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "diff" + }, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [0, 0], + [1, 0], + [1, 0.25], + [0.25, 0.25], + [0.25, 1], + [0, 1], + [0, 0] + ] + ], + [ + [ + [0.25, 1], + [1, 1], + [1, 0.25], + [2.75, 0.25], + [2.75, 2], + [2, 2], + [2, 2.75], + [0.25, 2.75], + [0.25, 1] + ] + ], + [ + [ + [2, 2.75], + [2.75, 2.75], + [2.75, 2], + [3, 2], + [3, 3], + [2, 3], + [2, 2.75] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "xor" + }, + "type": "Feature" + } + ], + "type": "FeatureCollection" +} diff --git a/test/genericTestCases/checkerboard1.geojson b/test/genericTestCases/checkerboard1.geojson new file mode 100644 index 0000000..9c55a5a --- /dev/null +++ b/test/genericTestCases/checkerboard1.geojson @@ -0,0 +1,132 @@ +{ + "features": [ + { + "geometry": { + "coordinates": [ + [ + [ + [0, 0], + [0, 1], + [1, 1], + [1, 0], + [0, 0] + ] + ], + [ + [ + [0, 2], + [0, 3], + [1, 3], + [1, 2], + [0, 2] + ] + ], + [ + [ + [1, 1], + [1, 2], + [2, 2], + [2, 1], + [1, 1] + ] + ], + [ + [ + [2, 0], + [2, 1], + [3, 1], + [3, 0], + [2, 0] + ] + ], + [ + [ + [2, 2], + [2, 3], + [3, 3], + [3, 2], + [2, 2] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [0, 1], + [0, 2], + [1, 2], + [1, 1], + [0, 1] + ] + ], + [ + [ + [1, 0], + [1, 1], + [2, 1], + [2, 0], + [1, 0] + ] + ], + [ + [ + [1, 2], + [1, 3], + [2, 3], + [2, 2], + [1, 2] + ] + ], + [ + [ + [2, 1], + [2, 2], + [3, 2], + [3, 1], + [2, 1] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [0, 0], + [1, 0], + [2, 0], + [3, 0], + [3, 1], + [3, 2], + [3, 3], + [2, 3], + [1, 3], + [0, 3], + [0, 2], + [0, 1], + [0, 0] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "union" + }, + "type": "Feature" + } + ], + "type": "FeatureCollection" +} diff --git a/test/genericTestCases/collinear_segments1.geojson b/test/genericTestCases/collinear_segments1.geojson new file mode 100644 index 0000000..ecb5db5 --- /dev/null +++ b/test/genericTestCases/collinear_segments1.geojson @@ -0,0 +1,106 @@ +{ + "features": [ + { + "geometry": { + "coordinates": [ + [ + [ + [0, 0], + [0, 0.25], + [0, 0.5], + [0, 0.75], + [0, 1], + [0.25, 1], + [0.5, 1], + [0.75, 1], + [1, 1], + [1, 0.75], + [1, 0.5], + [1, 0.25], + [1, 0], + [0.75, 0], + [0.5, 0], + [0.25, 0], + [0, 0] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [0, 0.25], + [0, 0.5], + [0, 0.75], + [0, 1], + [0, 1.25], + [0.25, 1.25], + [0.5, 1.25], + [0.75, 1.25], + [1, 1.25], + [1, 1], + [1, 0.75], + [1, 0.5], + [1, 0.25], + [0.75, 0.25], + [0.5, 0.25], + [0.25, 0.25], + [0, 0.25] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [0, 0], + [0.25, 0], + [0.5, 0], + [0.75, 0], + [1, 0], + [1, 0.25], + [0.75, 0.25], + [0.5, 0.25], + [0.25, 0.25], + [0, 0.25], + [0, 0] + ] + ], + [ + [ + [0, 1], + [0.25, 1], + [0.5, 1], + [0.75, 1], + [1, 1], + [1, 1.25], + [0.75, 1.25], + [0.5, 1.25], + [0.25, 1.25], + [0, 1.25], + [0, 1] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "xor" + }, + "type": "Feature" + } + ], + "type": "FeatureCollection" +} diff --git a/test/genericTestCases/daef_polygonwithholes_holed.geojson b/test/genericTestCases/daef_polygonwithholes_holed.geojson new file mode 100644 index 0000000..b7c77a3 --- /dev/null +++ b/test/genericTestCases/daef_polygonwithholes_holed.geojson @@ -0,0 +1,95 @@ +{ + "features": [ + { + "geometry": { + "coordinates": [ + [ + [0, 0], + [300, 0], + [150, 300], + [0, 0] + ], + [ + [50, 50], + [150, 250], + [250, 50], + [50, 50] + ], + [ + [100, 100], + [200, 100], + [150, 200], + [100, 100] + ] + ], + "type": "Polygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [0, 0], + [300, 0], + [150, 300], + [0, 0], + [0, 300], + [0, 0] + ], + [ + [60, 60], + [150, 240], + [240, 60], + [60, 60] + ] + ], + "type": "Polygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [0, 0], + [0, 300], + [0, 0] + ] + ], + [ + [ + [50, 50], + [250, 50], + [150, 250], + [50, 50] + ], + [ + [60, 60], + [240, 60], + [150, 240], + [60, 60] + ] + ], + [ + [ + [100, 100], + [200, 100], + [150, 200], + [100, 100] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "xor" + }, + "type": "Feature" + } + ], + "type": "FeatureCollection" +} diff --git a/test/genericTestCases/intersections_at_endpoints.geojson b/test/genericTestCases/intersections_at_endpoints.geojson new file mode 100644 index 0000000..b76a0a4 --- /dev/null +++ b/test/genericTestCases/intersections_at_endpoints.geojson @@ -0,0 +1,93 @@ +{ + "features": [ + { + "geometry": { + "coordinates": [ + [ + [ + [-9, 10], + [9, 10], + [0.1, 0.1], + [10, 9], + [10, -9], + [0.1, -0.1], + [9, -10], + [-9, -10], + [-0.1, -0.1], + [-10, -9], + [-10, 9], + [-0.1, 0.1], + [-9, 10] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [-8.99999, 10], + [8.99999, 10], + [0.1, 0.1], + [10, 8.99999], + [10, -8.99999], + [0.1, -0.1], + [8.99999, -10], + [-8.99999, -10], + [-0.1, -0.1], + [-10, -8.99999], + [-10, 8.99999], + [-0.1, 0.1], + [-8.99999, 10] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [-10, -9], + [-0.1, -0.1], + [-9, -10], + [-8.99999, -10], + [8.99999, -10], + [9, -10], + [0.1, -0.1], + [10, -9], + [10, -8.99999], + [10, 8.99999], + [10, 9], + [0.1, 0.1], + [9, 10], + [8.99999, 10], + [-8.99999, 10], + [-9, 10], + [-0.1, 0.1], + [-10, 9], + [-10, 8.99999], + [-10, -8.99999], + [-10, -9] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "union" + }, + "type": "Feature" + } + ], + "type": "FeatureCollection" +} diff --git a/test/genericTestCases/overlapping_segments1.geojson b/test/genericTestCases/overlapping_segments1.geojson new file mode 100644 index 0000000..fe552fe --- /dev/null +++ b/test/genericTestCases/overlapping_segments1.geojson @@ -0,0 +1,132 @@ +{ + "features": [ + { + "geometry": { + "coordinates": [ + [ + [ + [10, 10], + [15, 10], + [15, 20], + [10, 10] + ] + ], + [ + [ + [10, -10], + [15, -10], + [15, -20], + [10, -10] + ] + ], + [ + [ + [20, 10], + [25, 10], + [25, 20], + [20, 10] + ] + ], + [ + [ + [20, -10], + [25, -10], + [25, -20], + [20, -10] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [10, 10], + [15, 10], + [15, 15], + [10, 10] + ] + ], + [ + [ + [10, -10], + [15, -10], + [15, -15], + [10, -10] + ] + ], + [ + [ + [20, 10], + [25, 10], + [25, 5], + [20, 10] + ] + ], + [ + [ + [20, -10], + [25, -10], + [25, -5], + [20, -10] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [10, -10], + [15, -20], + [15, -15], + [10, -10] + ] + ], + [ + [ + [10, 10], + [15, 15], + [15, 20], + [10, 10] + ] + ], + [ + [ + [20, -10], + [25, -20], + [25, -10], + [25, -5], + [20, -10] + ] + ], + [ + [ + [20, 10], + [25, 5], + [25, 10], + [25, 20], + [20, 10] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "xor" + }, + "type": "Feature" + } + ], + "type": "FeatureCollection" +} diff --git a/test/genericTestCases/overlapping_segments2.geojson b/test/genericTestCases/overlapping_segments2.geojson new file mode 100644 index 0000000..0ea8081 --- /dev/null +++ b/test/genericTestCases/overlapping_segments2.geojson @@ -0,0 +1,336 @@ +{ + "features": [ + { + "geometry": { + "coordinates": [ + [ + [ + [2, -1], + [2, 1], + [3, 1], + [3, -1], + [2, -1] + ] + ], + [ + [ + [4, -1], + [4, 1], + [5, 1], + [5, -1], + [4, -1] + ] + ], + [ + [ + [6, -1], + [6, 1], + [7, 1], + [7, -1], + [6, -1] + ] + ], + [ + [ + [8, -1], + [8, 1], + [9, 1], + [9, -1], + [8, -1] + ] + ], + [ + [ + [10, -1], + [10, 1], + [11, 1], + [11, -1], + [10, -1] + ] + ], + [ + [ + [12, -1], + [12, 1], + [13, 1], + [13, -1], + [12, -1] + ] + ], + [ + [ + [14, -1], + [14, 1], + [15, 1], + [15, -1], + [14, -1] + ] + ], + [ + [ + [16, -1], + [16, 1], + [17, 1], + [17, -1], + [16, -1] + ] + ], + [ + [ + [18, -1], + [18, 1], + [19, 1], + [19, -1], + [18, -1] + ] + ], + [ + [ + [20, -1], + [20, 1], + [21, 1], + [21, -1], + [20, -1] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [2, 1], + [2, 2], + [2.5, 2], + [2.5, 1], + [2, 1] + ] + ], + [ + [ + [4.5, 1], + [4.5, 2], + [5, 2], + [5, 1], + [4.5, 1] + ] + ], + [ + [ + [6.25, 1], + [6.25, 2], + [6.75, 2], + [6.75, 1], + [6.25, 1] + ] + ], + [ + [ + [8, 1], + [8, 2], + [9, 2], + [9, 1], + [8, 1] + ] + ], + [ + [ + [9.5, 1], + [9.5, 2], + [10.5, 2], + [10.5, 1], + [9.5, 1] + ] + ], + [ + [ + [12, -1], + [12, -2], + [12.5, -2], + [12.5, -1], + [12, -1] + ] + ], + [ + [ + [14.5, -1], + [14.5, -2], + [15, -2], + [15, -1], + [14.5, -1] + ] + ], + [ + [ + [16.25, -1], + [16.25, -2], + [16.75, -2], + [16.75, -1], + [16.25, -1] + ] + ], + [ + [ + [18, -1], + [18, -2], + [19, -2], + [19, -1], + [18, -1] + ] + ], + [ + [ + [19.5, -1], + [19.5, -2], + [20.5, -2], + [20.5, -1], + [19.5, -1] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [2, -1], + [3, -1], + [3, 1], + [2.5, 1], + [2.5, 2], + [2, 2], + [2, 1], + [2, -1] + ] + ], + [ + [ + [4, -1], + [5, -1], + [5, 1], + [5, 2], + [4.5, 2], + [4.5, 1], + [4, 1], + [4, -1] + ] + ], + [ + [ + [6, -1], + [7, -1], + [7, 1], + [6.75, 1], + [6.75, 2], + [6.25, 2], + [6.25, 1], + [6, 1], + [6, -1] + ] + ], + [ + [ + [8, -1], + [9, -1], + [9, 1], + [9, 2], + [8, 2], + [8, 1], + [8, -1] + ] + ], + [ + [ + [9.5, 1], + [10, 1], + [10, -1], + [11, -1], + [11, 1], + [10.5, 1], + [10.5, 2], + [9.5, 2], + [9.5, 1] + ] + ], + [ + [ + [12, -2], + [12.5, -2], + [12.5, -1], + [13, -1], + [13, 1], + [12, 1], + [12, -1], + [12, -2] + ] + ], + [ + [ + [14, -1], + [14.5, -1], + [14.5, -2], + [15, -2], + [15, -1], + [15, 1], + [14, 1], + [14, -1] + ] + ], + [ + [ + [16, -1], + [16.25, -1], + [16.25, -2], + [16.75, -2], + [16.75, -1], + [17, -1], + [17, 1], + [16, 1], + [16, -1] + ] + ], + [ + [ + [18, -2], + [19, -2], + [19, -1], + [19, 1], + [18, 1], + [18, -1], + [18, -2] + ] + ], + [ + [ + [19.5, -2], + [20.5, -2], + [20.5, -1], + [21, -1], + [21, 1], + [20, 1], + [20, -1], + [19.5, -1], + [19.5, -2] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "union" + }, + "type": "Feature" + } + ], + "type": "FeatureCollection" +} diff --git a/test/genericTestCases/overlapping_segments3.geojson b/test/genericTestCases/overlapping_segments3.geojson new file mode 100644 index 0000000..37b6ecb --- /dev/null +++ b/test/genericTestCases/overlapping_segments3.geojson @@ -0,0 +1,66 @@ +{ + "features": [ + { + "geometry": { + "coordinates": [ + [ + [ + [384, 0], + [416, 0], + [448, 0], + [448, 32], + [416, 32], + [384, 32], + [384, 0] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [400, 32], + [416, 32], + [416, 48], + [400, 32] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": {}, + "type": "Feature" + }, + { + "geometry": { + "coordinates": [ + [ + [ + [384, 0], + [416, 0], + [448, 0], + [448, 32], + [416, 32], + [416, 48], + [400, 32], + [384, 32], + [384, 0] + ] + ] + ], + "type": "MultiPolygon" + }, + "properties": { + "operation": "union" + }, + "type": "Feature" + } + ], + "type": "FeatureCollection" +} diff --git a/test/index.test.js b/test/index.test.js deleted file mode 100644 index 92c4c14..0000000 --- a/test/index.test.js +++ /dev/null @@ -1,161 +0,0 @@ -import tap from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import martinez from '../'; -import fillQueue from '../src/fill_queue'; - -// GeoJSON Data -const data = load.sync(path.join(__dirname, 'fixtures', 'two_triangles.geojson')); - -const subject = data.features[0]; -const clipping = data.features[1]; - -tap.test('fill event queue', (main) => { - const s = [subject.geometry.coordinates]; - const c = [clipping.geometry.coordinates]; - - const sbbox = [Infinity, Infinity, -Infinity, -Infinity]; - const cbbox = [Infinity, Infinity, -Infinity, -Infinity]; - const q = fillQueue(s, c, sbbox, cbbox); - let currentPoint; - - main.test('bboxes', (t) => { - t.deepEqual(sbbox, [20, -113.5, 226.5, 74], 'subject bbox'); - t.deepEqual(cbbox, [54.5, -198, 239.5, 33.5], 'clipping bbox'); - t.end(); - }); - - main.test('point 0', (t) => { - currentPoint = q.pop(); - t.deepEqual(currentPoint.point, [20, -23.5]); /* s[0][0] */ - t.ok(currentPoint.left, 'is left'); - t.deepEqual(currentPoint.otherEvent.point, [226.5, -113.5], 'other event'); /* s[0][2] */ - t.notOk(currentPoint.otherEvent.left, 'other event is right'); - - t.end(); - }); - - - main.test('point 1', (t) => { - currentPoint = q.pop(); - t.deepEqual(currentPoint.point, [20, -23.5]); /* s[0][0] */ - t.ok(currentPoint.left, 'is left'); - t.deepEqual(currentPoint.otherEvent.point, [170, 74], 'other event'); /* s[0][1] */ - t.notOk(currentPoint.otherEvent.left, 'other event is right'); - - t.end(); - }); - - - main.test('point 2', (t) => { - currentPoint = q.pop(); - t.deepEqual(currentPoint.point, [54.5, -170.5]); /* c[0][0] */ - t.ok(currentPoint.left, 'is left'); - t.deepEqual(currentPoint.otherEvent.point, [239.5, -198], 'other event'); /* c[0][2] */ - t.notOk(currentPoint.otherEvent.left, 'other event is right'); - - t.end(); - }); - - - main.test('point 3', (t) => { - currentPoint = q.pop(); - t.deepEqual(currentPoint.point, [54.5, -170.5]); /* c[0][0] */ - t.ok(currentPoint.left, 'is left'); - t.deepEqual(currentPoint.otherEvent.point, [140.5, 33.5], 'other event'); /* c[0][1] */ - t.notOk(currentPoint.otherEvent.left, 'other event is right'); - - t.end(); - }); - - - main.test('point 4', (t) => { - currentPoint = q.pop(); - t.deepEqual(currentPoint.point, [140.5, 33.5]); /* c[0][0] */ - t.notOk(currentPoint.left, 'is right'); - t.deepEqual(currentPoint.otherEvent.point, [54.5, -170.5], 'other event'); /* c[0][1] */ - t.ok(currentPoint.otherEvent.left, 'other event is left'); - - t.end(); - }); - - - main.test('point 5', (t) => { - currentPoint = q.pop(); - t.deepEqual(currentPoint.point, [140.5, 33.5]); /* c[0][0] */ - t.ok(currentPoint.left, 'is left'); - t.deepEqual(currentPoint.otherEvent.point, [239.5, -198], 'other event'); /* c[0][1] */ - t.notOk(currentPoint.otherEvent.left, 'other event is right'); - - t.end(); - }); - - - main.test('point 6', (t) => { - currentPoint = q.pop(); - t.deepEqual(currentPoint.point, [170, 74]); /* s[0][1] */ - t.notOk(currentPoint.left, 'is right'); - t.deepEqual(currentPoint.otherEvent.point, [20, -23.5], 'other event'); /* s[0][0] */ - t.ok(currentPoint.otherEvent.left, 'other event is left'); - - t.end(); - }); - - - main.test('point 7', (t) => { - currentPoint = q.pop(); - t.deepEqual(currentPoint.point, [170, 74]); /* s[0][1] */ - t.ok(currentPoint.left, 'is left'); - t.deepEqual(currentPoint.otherEvent.point, [226.5, -113.5], 'other event'); /* s[0][3] */ - t.notOk(currentPoint.otherEvent.left, 'other event is right'); - - t.end(); - }); - - - main.test('point 8', (t) => { - currentPoint = q.pop(); - t.deepEqual(currentPoint.point, [226.5, -113.5]); /* s[0][1] */ - t.notOk(currentPoint.left, 'is right'); - t.deepEqual(currentPoint.otherEvent.point, [20, -23.5], 'other event'); /* s[0][0] */ - t.ok(currentPoint.otherEvent.left, 'other event is left'); - - t.end(); - }); - - - main.test('point 9', (t) => { - currentPoint = q.pop(); - t.deepEqual(currentPoint.point, [226.5, -113.5]); /* s[0][1] */ - t.notOk(currentPoint.left, 'is right'); - t.deepEqual(currentPoint.otherEvent.point, [170, 74], 'other event'); /* s[0][0] */ - t.ok(currentPoint.otherEvent.left, 'other event is left'); - - t.end(); - }); - - - main.test('point 10', (t) => { - currentPoint = q.pop(); - t.deepEqual(currentPoint.point, [239.5, -198]); /* c[0][2] */ - t.notOk(currentPoint.left, 'is right'); - t.deepEqual(currentPoint.otherEvent.point, [54.5, -170.5], 'other event'); /* c[0][0] */ - t.ok(currentPoint.otherEvent.left, 'other event is left'); - - t.end(); - }); - - - main.test('point 11', (t) => { - currentPoint = q.pop(); - t.deepEqual(currentPoint.point, [239.5, -198]); /* c[0][2] */ - t.notOk(currentPoint.left, 'is right'); - t.deepEqual(currentPoint.otherEvent.point, [140.5, 33.5], 'other event'); /* s[0][1] */ - t.ok(currentPoint.otherEvent.left, 'other event is left'); - - t.end(); - }); - - main.end(); -}); - diff --git a/test/index.test.ts b/test/index.test.ts new file mode 100644 index 0000000..1de81f8 --- /dev/null +++ b/test/index.test.ts @@ -0,0 +1,151 @@ +import { describe, it, expect } from 'vitest'; +import { readFileSync } from 'fs'; +import { join } from 'path'; +import fillQueue from '../src/fill_queue'; +import { INTERSECTION } from '../src/operation'; + +// GeoJSON Data +const data = JSON.parse(readFileSync(join(__dirname, 'fixtures', 'two_triangles.geojson'), 'utf-8')); + +const subject = data.features[0]; +const clipping = data.features[1]; + +describe('fill event queue', () => { + const s = [subject.geometry.coordinates]; + const c = [clipping.geometry.coordinates]; + + const sbbox: [number, number, number, number] = [Infinity, Infinity, -Infinity, -Infinity]; + const cbbox: [number, number, number, number] = [Infinity, Infinity, -Infinity, -Infinity]; + const q = fillQueue(s, c, sbbox, cbbox, INTERSECTION); + let currentPoint: any; + + describe('bboxes', () => { + it('should have correct subject bbox', () => { + expect(sbbox).toEqual([20, -113.5, 226.5, 74]); + }); + + it('should have correct clipping bbox', () => { + expect(cbbox).toEqual([54.5, -198, 239.5, 33.5]); + }); + }); + + describe('point 0', () => { + it('should have correct properties', () => { + currentPoint = q.pop(); + expect(currentPoint.point).toEqual([20, -23.5]); /* s[0][0] */ + expect(currentPoint.left).toBeTruthy(); + expect(currentPoint.otherEvent.point).toEqual([226.5, -113.5]); /* s[0][2] */ + expect(currentPoint.otherEvent.left).toBeFalsy(); + }); + }); + + describe('point 1', () => { + it('should have correct properties', () => { + currentPoint = q.pop(); + expect(currentPoint.point).toEqual([20, -23.5]); /* s[0][0] */ + expect(currentPoint.left).toBeTruthy(); + expect(currentPoint.otherEvent.point).toEqual([170, 74]); /* s[0][1] */ + expect(currentPoint.otherEvent.left).toBeFalsy(); + }); + }); + + describe('point 2', () => { + it('should have correct properties', () => { + currentPoint = q.pop(); + expect(currentPoint.point).toEqual([54.5, -170.5]); /* c[0][0] */ + expect(currentPoint.left).toBeTruthy(); + expect(currentPoint.otherEvent.point).toEqual([239.5, -198]); /* c[0][2] */ + expect(currentPoint.otherEvent.left).toBeFalsy(); + }); + }); + + describe('point 3', () => { + it('should have correct properties', () => { + currentPoint = q.pop(); + expect(currentPoint.point).toEqual([54.5, -170.5]); /* c[0][0] */ + expect(currentPoint.left).toBeTruthy(); + expect(currentPoint.otherEvent.point).toEqual([140.5, 33.5]); /* c[0][1] */ + expect(currentPoint.otherEvent.left).toBeFalsy(); + }); + }); + + describe('point 4', () => { + it('should have correct properties', () => { + currentPoint = q.pop(); + expect(currentPoint.point).toEqual([140.5, 33.5]); /* c[0][0] */ + expect(currentPoint.left).toBeFalsy(); + expect(currentPoint.otherEvent.point).toEqual([54.5, -170.5]); /* c[0][1] */ + expect(currentPoint.otherEvent.left).toBeTruthy(); + }); + }); + + describe('point 5', () => { + it('should have correct properties', () => { + currentPoint = q.pop(); + expect(currentPoint.point).toEqual([140.5, 33.5]); /* c[0][0] */ + expect(currentPoint.left).toBeTruthy(); + expect(currentPoint.otherEvent.point).toEqual([239.5, -198]); /* c[0][1] */ + expect(currentPoint.otherEvent.left).toBeFalsy(); + }); + }); + + describe('point 6', () => { + it('should have correct properties', () => { + currentPoint = q.pop(); + expect(currentPoint.point).toEqual([170, 74]); /* s[0][1] */ + expect(currentPoint.left).toBeFalsy(); + expect(currentPoint.otherEvent.point).toEqual([20, -23.5]); /* s[0][0] */ + expect(currentPoint.otherEvent.left).toBeTruthy(); + }); + }); + + describe('point 7', () => { + it('should have correct properties', () => { + currentPoint = q.pop(); + expect(currentPoint.point).toEqual([170, 74]); /* s[0][1] */ + expect(currentPoint.left).toBeTruthy(); + expect(currentPoint.otherEvent.point).toEqual([226.5, -113.5]); /* s[0][3] */ + expect(currentPoint.otherEvent.left).toBeFalsy(); + }); + }); + + describe('point 8', () => { + it('should have correct properties', () => { + currentPoint = q.pop(); + expect(currentPoint.point).toEqual([226.5, -113.5]); /* s[0][1] */ + expect(currentPoint.left).toBeFalsy(); + expect(currentPoint.otherEvent.point).toEqual([20, -23.5]); /* s[0][0] */ + expect(currentPoint.otherEvent.left).toBeTruthy(); + }); + }); + + describe('point 9', () => { + it('should have correct properties', () => { + currentPoint = q.pop(); + expect(currentPoint.point).toEqual([226.5, -113.5]); /* s[0][1] */ + expect(currentPoint.left).toBeFalsy(); + expect(currentPoint.otherEvent.point).toEqual([170, 74]); /* s[0][0] */ + expect(currentPoint.otherEvent.left).toBeTruthy(); + }); + }); + + describe('point 10', () => { + it('should have correct properties', () => { + currentPoint = q.pop(); + expect(currentPoint.point).toEqual([239.5, -198]); /* c[0][2] */ + expect(currentPoint.left).toBeFalsy(); + expect(currentPoint.otherEvent.point).toEqual([54.5, -170.5]); /* c[0][0] */ + expect(currentPoint.otherEvent.left).toBeTruthy(); + }); + }); + + describe('point 11', () => { + it('should have correct properties', () => { + currentPoint = q.pop(); + expect(currentPoint.point).toEqual([239.5, -198]); /* c[0][2] */ + expect(currentPoint.left).toBeFalsy(); + expect(currentPoint.otherEvent.point).toEqual([140.5, 33.5]); /* s[0][1] */ + expect(currentPoint.otherEvent.left).toBeTruthy(); + }); + }); +}); \ No newline at end of file diff --git a/test/segment_intersection.test.js b/test/segment_intersection.test.js deleted file mode 100644 index 8b3a56f..0000000 --- a/test/segment_intersection.test.js +++ /dev/null @@ -1,41 +0,0 @@ -import tap from 'tape'; -import intersection from '../src/segment_intersection'; - -tap.test('intersection', (t) => { - - t.deepEqual(intersection([0, 0], [1, 1], [1, 0], [2, 2]), null, 'null if no intersections'); - t.deepEqual(intersection([0, 0], [1, 1], [1, 0], [10, 2]), null, 'null if no intersections'); - t.deepEqual(intersection([2, 2], [3, 3], [0, 6], [2, 4]), null, 'null if no intersections'); - - t.deepEqual(intersection([0, 0], [1, 1], [1, 0], [0, 1]), [[0.5, 0.5]], '1 intersection'); - t.deepEqual(intersection([0, 0], [1, 1], [0, 1], [0, 0]), [[0, 0]], 'shared point 1'); - t.deepEqual(intersection([0, 0], [1, 1], [0, 1], [1, 1]), [[1, 1]], 'shared point 2'); - - t.deepEqual(intersection([0, 0], [1, 1], [0.5, 0.5], [1, 0]), [[0.5, 0.5]], 'T-crossing'); - - t.deepEqual(intersection([0, 0], [10, 10], [1, 1], [5, 5]), [[1, 1], [5, 5]], 'full overlap'); - t.deepEqual(intersection([1, 1], [10, 10], [1, 1], [5, 5]), [[1, 1], [5, 5]], 'shared point + overlap'); - t.deepEqual(intersection([3, 3], [10, 10], [0, 0], [5, 5]), [[3, 3], [5, 5]], 'mutual overlap'); - t.deepEqual(intersection([0, 0], [1, 1], [0, 0], [1, 1]), [[0, 0], [1, 1]], 'full overlap'); - t.deepEqual(intersection([1, 1], [0, 0], [0, 0], [1, 1]), [[1, 1], [0, 0]], 'full overlap, orientation'); - - t.deepEqual(intersection([0, 0], [1, 1], [1, 1], [2, 2]), [[1, 1]], 'collinear, shared point'); - t.deepEqual(intersection([1, 1], [0, 0], [1, 1], [2, 2]), [[1, 1]], 'collinear, shared other point'); - t.deepEqual(intersection([0, 0], [1, 1], [2, 2], [4, 4]), null, 'collinear, no overlap'); - t.deepEqual(intersection([0, 0], [1, 1], [0, -1], [1, 0]), null, 'parallel'); - t.deepEqual(intersection([1, 1], [0, 0], [0, -1], [1, 0]), null, 'parallel, orientation'); - t.deepEqual(intersection([0, -1], [1, 0], [0, 0], [1, 1]), null, 'parallel, position'); - - t.deepEqual(intersection([0, 0], [1, 1], [0, 1], [0, 0], true), null, 'shared point 1, skip touches'); - t.deepEqual(intersection([0, 0], [1, 1], [0, 1], [1, 1], true), null, 'shared point 2, skip touches'); - - t.deepEqual(intersection([0, 0], [1, 1], [1, 1], [2, 2], true), null, 'collinear, shared point, skip touches'); - t.deepEqual(intersection([1, 1], [0, 0], [1, 1], [2, 2], true), null, 'collinear, shared other point, skip touches'); - - t.deepEqual(intersection([0, 0], [1, 1], [0, 0], [1, 1], true), null, 'full overlap, skip touches'); - t.deepEqual(intersection([1, 1], [0, 0], [0, 0], [1, 1], true), null, 'full overlap, orientation, skip touches'); - - t.deepEqual(intersection([0, 0], [1, 1], [1, 0], [0, 1], true), [[0.5, 0.5]], '1 intersection, skip touches'); - - t.end(); -}); diff --git a/test/segment_intersection.test.ts b/test/segment_intersection.test.ts new file mode 100644 index 0000000..49aa0c6 --- /dev/null +++ b/test/segment_intersection.test.ts @@ -0,0 +1,62 @@ +import { describe, it, expect } from 'vitest'; +import intersection from '../src/segment_intersection'; + +describe('segment intersection', () => { + it('should return null when no intersections exist', () => { + expect(intersection([0, 0], [1, 1], [1, 0], [2, 2])).toBe(null); + expect(intersection([0, 0], [1, 1], [1, 0], [10, 2])).toBe(null); + expect(intersection([2, 2], [3, 3], [0, 6], [2, 4])).toBe(null); + }); + + it('should find single intersections', () => { + expect(intersection([0, 0], [1, 1], [1, 0], [0, 1])).toEqual([[0.5, 0.5]]); + }); + + it('should handle shared points', () => { + expect(intersection([0, 0], [1, 1], [0, 1], [0, 0])).toEqual([[0, 0]]); + expect(intersection([0, 0], [1, 1], [0, 1], [1, 1])).toEqual([[1, 1]]); + }); + + it('should handle T-crossings', () => { + expect(intersection([0, 0], [1, 1], [0.5, 0.5], [1, 0])).toEqual([[0.5, 0.5]]); + }); + + it('should handle overlapping segments', () => { + expect(intersection([0, 0], [10, 10], [1, 1], [5, 5])).toEqual([[1, 1], [5, 5]]); + expect(intersection([1, 1], [10, 10], [1, 1], [5, 5])).toEqual([[1, 1], [5, 5]]); + expect(intersection([3, 3], [10, 10], [0, 0], [5, 5])).toEqual([[3, 3], [5, 5]]); + expect(intersection([0, 0], [1, 1], [0, 0], [1, 1])).toEqual([[0, 0], [1, 1]]); + expect(intersection([1, 1], [0, 0], [0, 0], [1, 1])).toEqual([[1, 1], [0, 0]]); + }); + + it('should handle collinear segments', () => { + expect(intersection([0, 0], [1, 1], [1, 1], [2, 2])).toEqual([[1, 1]]); + expect(intersection([1, 1], [0, 0], [1, 1], [2, 2])).toEqual([[1, 1]]); + expect(intersection([0, 0], [1, 1], [2, 2], [4, 4])).toBe(null); + }); + + it('should handle parallel segments', () => { + expect(intersection([0, 0], [1, 1], [0, -1], [1, 0])).toBe(null); + expect(intersection([1, 1], [0, 0], [0, -1], [1, 0])).toBe(null); + expect(intersection([0, -1], [1, 0], [0, 0], [1, 1])).toBe(null); + }); + + it('should handle skip touches option for shared points', () => { + expect(intersection([0, 0], [1, 1], [0, 1], [0, 0], true)).toBe(null); + expect(intersection([0, 0], [1, 1], [0, 1], [1, 1], true)).toBe(null); + }); + + it('should handle skip touches option for collinear segments', () => { + expect(intersection([0, 0], [1, 1], [1, 1], [2, 2], true)).toBe(null); + expect(intersection([1, 1], [0, 0], [1, 1], [2, 2], true)).toBe(null); + }); + + it('should handle skip touches option for overlapping segments', () => { + expect(intersection([0, 0], [1, 1], [0, 0], [1, 1], true)).toBe(null); + expect(intersection([1, 1], [0, 0], [0, 0], [1, 1], true)).toBe(null); + }); + + it('should find intersections with skip touches option when not touching', () => { + expect(intersection([0, 0], [1, 1], [1, 0], [0, 1], true)).toEqual([[0.5, 0.5]]); + }); +}); \ No newline at end of file diff --git a/test/signed_area.test.js b/test/signed_area.test.js deleted file mode 100644 index 548865a..0000000 --- a/test/signed_area.test.js +++ /dev/null @@ -1,14 +0,0 @@ -import tap from 'tape'; -import signedArea from '../src/signed_area'; - -tap.test('analytical signed area', (t) => { - - t.equals(signedArea([0, 0], [0, 1], [1, 1]), -1, 'negative area'); - t.equals(signedArea([0, 1], [0, 0], [1, 0]), 1, 'positive area'); - t.equals(signedArea([0, 0], [1, 1], [2, 2]), 0, 'collinear, 0 area'); - - t.equals(signedArea([-1, 0], [2, 3], [0, 1]), 0, 'point on segment'); - t.equals(signedArea([2, 3], [-1, 0], [0, 1]), 0, 'point on segment'); - - t.end(); -}); diff --git a/test/signed_area.test.ts b/test/signed_area.test.ts new file mode 100644 index 0000000..334371d --- /dev/null +++ b/test/signed_area.test.ts @@ -0,0 +1,21 @@ +import { describe, it, expect } from 'vitest'; +import signedArea from '../src/signed_area'; + +describe('analytical signed area', () => { + it('should calculate negative area', () => { + expect(signedArea([0, 0], [0, 1], [1, 1])).toBe(-1); + }); + + it('should calculate positive area', () => { + expect(signedArea([0, 1], [0, 0], [1, 0])).toBe(1); + }); + + it('should calculate collinear 0 area', () => { + expect(signedArea([0, 0], [1, 1], [2, 2])).toBe(0); + }); + + it('should handle point on segment', () => { + expect(signedArea([-1, 0], [2, 3], [0, 1])).toBe(0); + expect(signedArea([2, 3], [-1, 0], [0, 1])).toBe(0); + }); +}); \ No newline at end of file diff --git a/test/sweep_event.test.js b/test/sweep_event.test.js deleted file mode 100644 index da738fa..0000000 --- a/test/sweep_event.test.js +++ /dev/null @@ -1,52 +0,0 @@ -import tap from 'tape'; -import SweepEvent from '../src/sweep_event'; - -tap.test('sweep event', (main) => { - - main.test('isBelow', (t) => { - const s1 = new SweepEvent([0, 0], true, new SweepEvent([1, 1], false)); - const s2 = new SweepEvent([0, 1], false, new SweepEvent([0, 0], false)); - - t.ok(s1.isBelow([0, 1])); - t.ok(s1.isBelow([1, 2])); - t.notOk(s1.isBelow([0, 0])); - t.notOk(s1.isBelow([5, -1])); - - t.notOk(s2.isBelow([0, 1])); - t.notOk(s2.isBelow([1, 2])); - t.notOk(s2.isBelow([0, 0])); - t.notOk(s2.isBelow([5, -1])); - - t.end(); - }); - - - main.test('isAbove', (t) => { - - const s1 = new SweepEvent([0, 0], true, new SweepEvent([1, 1], false)); - const s2 = new SweepEvent([0, 1], false, new SweepEvent([0, 0], false)); - - t.notOk(s1.isAbove([0, 1])); - t.notOk(s1.isAbove([1, 2])); - t.ok(s1.isAbove([0, 0])); - t.ok(s1.isAbove([5, -1])); - - t.ok(s2.isAbove([0, 1])); - t.ok(s2.isAbove([1, 2])); - t.ok(s2.isAbove([0, 0])); - t.ok(s2.isAbove([5, -1])); - - t.end(); - }); - - - main.test('isVertical', (t) => { - t.ok(new SweepEvent([0, 0], true, new SweepEvent([0, 1], false)).isVertical()); - t.notOk(new SweepEvent([0, 0], true, new SweepEvent([0.0001, 1], false)).isVertical()); - - t.end(); - }); - - - main.end(); -}); diff --git a/test/sweep_event.test.ts b/test/sweep_event.test.ts new file mode 100644 index 0000000..8ca6118 --- /dev/null +++ b/test/sweep_event.test.ts @@ -0,0 +1,54 @@ +import { describe, it, expect } from 'vitest'; +import SweepEvent from '../src/sweep_event'; + +describe('sweep event', () => { + describe('isBelow', () => { + it('should correctly determine if point is below for left sweep event', () => { + const s1 = new SweepEvent([0, 0], true, new SweepEvent([1, 1], false)); + + expect(s1.isBelow([0, 1])).toBeTruthy(); + expect(s1.isBelow([1, 2])).toBeTruthy(); + expect(s1.isBelow([0, 0])).toBeFalsy(); + expect(s1.isBelow([5, -1])).toBeFalsy(); + }); + + it('should correctly determine if point is below for right sweep event', () => { + const s2 = new SweepEvent([0, 1], false, new SweepEvent([0, 0], false)); + + expect(s2.isBelow([0, 1])).toBeFalsy(); + expect(s2.isBelow([1, 2])).toBeFalsy(); + expect(s2.isBelow([0, 0])).toBeFalsy(); + expect(s2.isBelow([5, -1])).toBeFalsy(); + }); + }); + + describe('isAbove', () => { + it('should correctly determine if point is above for left sweep event', () => { + const s1 = new SweepEvent([0, 0], true, new SweepEvent([1, 1], false)); + + expect(s1.isAbove([0, 1])).toBeFalsy(); + expect(s1.isAbove([1, 2])).toBeFalsy(); + expect(s1.isAbove([0, 0])).toBeTruthy(); + expect(s1.isAbove([5, -1])).toBeTruthy(); + }); + + it('should correctly determine if point is above for right sweep event', () => { + const s2 = new SweepEvent([0, 1], false, new SweepEvent([0, 0], false)); + + expect(s2.isAbove([0, 1])).toBeTruthy(); + expect(s2.isAbove([1, 2])).toBeTruthy(); + expect(s2.isAbove([0, 0])).toBeTruthy(); + expect(s2.isAbove([5, -1])).toBeTruthy(); + }); + }); + + describe('isVertical', () => { + it('should detect vertical segments', () => { + expect(new SweepEvent([0, 0], true, new SweepEvent([0, 1], false)).isVertical()).toBeTruthy(); + }); + + it('should detect non-vertical segments', () => { + expect(new SweepEvent([0, 0], true, new SweepEvent([0.0001, 1], false)).isVertical()).toBeFalsy(); + }); + }); +}); \ No newline at end of file diff --git a/test/sweep_line.test.js b/test/sweep_line.test.js deleted file mode 100644 index dab5f94..0000000 --- a/test/sweep_line.test.js +++ /dev/null @@ -1,58 +0,0 @@ -import tap from 'tape'; -import path from 'path'; -import Tree from 'splaytree'; -import load from 'load-json-file'; -import compareSegments from '../src/compare_segments'; -import SweepEvent from '../src/sweep_event'; - -// GeoJSON Data -const data = load.sync(path.join(__dirname, 'fixtures', 'two_triangles.geojson')); - -const subject = data.features[0]; -const clipping = data.features[1]; - -tap.test('sweep line', (t) => { - - const s = subject.geometry.coordinates; - const c = clipping.geometry.coordinates; - - const EF = new SweepEvent(s[0][0], true, new SweepEvent(s[0][2], false), true); - EF.name = 'EF'; - const EG = new SweepEvent(s[0][0], true, new SweepEvent(s[0][1], false), true); - EG.name = 'EG'; - - const tree = new Tree(compareSegments); - tree.insert(EF); - tree.insert(EG); - - - t.equals(tree.find(EF).key, EF, 'able to retrieve node'); - t.equals(tree.minNode().key, EF, 'EF is at the begin'); - t.equals(tree.maxNode().key, EG, 'EG is at the end'); - - let it = tree.find(EF); - - t.equals(tree.next(it).key, EG); - - it = tree.find(EG); - - t.equals(tree.prev(it).key, EF); - - const DA = new SweepEvent(c[0][0], true, new SweepEvent(c[0][2], false), true); - const DC = new SweepEvent(c[0][0], true, new SweepEvent(c[0][1], false), true); - - tree.insert(DA); - tree.insert(DC); - - let begin = tree.minNode(); - - t.equals(begin.key, DA, 'DA'); - begin = tree.next(begin); - t.equals(begin.key, DC, 'DC'); - begin = tree.next(begin); - t.equals(begin.key, EF, 'EF'); - begin = tree.next(begin); - t.equals(begin.key, EG, 'EG'); - - t.end(); -}); diff --git a/test/sweep_line.test.ts b/test/sweep_line.test.ts new file mode 100644 index 0000000..2439dc0 --- /dev/null +++ b/test/sweep_line.test.ts @@ -0,0 +1,56 @@ +import { describe, it, expect } from 'vitest'; +import { readFileSync } from 'fs'; +import { join } from 'path'; +import Tree from 'splaytree'; +import compareSegments from '../src/compare_segments'; +import SweepEvent from '../src/sweep_event'; + +// GeoJSON Data +const data = JSON.parse(readFileSync(join(__dirname, 'fixtures', 'two_triangles.geojson'), 'utf-8')); + +const subject = data.features[0]; +const clipping = data.features[1]; + +describe('sweep line', () => { + it('should manage sweep events in correct order using splay tree', () => { + const s = subject.geometry.coordinates; + const c = clipping.geometry.coordinates; + + const EF = new SweepEvent(s[0][0], true, new SweepEvent(s[0][2], false), true); + (EF as any).name = 'EF'; + const EG = new SweepEvent(s[0][0], true, new SweepEvent(s[0][1], false), true); + (EG as any).name = 'EG'; + + const tree = new Tree(compareSegments); + tree.insert(EF); + tree.insert(EG); + + expect(tree.find(EF).key).toBe(EF); + expect(tree.minNode().key).toBe(EF); + expect(tree.maxNode().key).toBe(EG); + + let it = tree.find(EF); + expect(tree.next(it).key).toBe(EG); + + it = tree.find(EG); + expect(tree.prev(it).key).toBe(EF); + + const DA = new SweepEvent(c[0][0], true, new SweepEvent(c[0][2], false), true); + const DC = new SweepEvent(c[0][0], true, new SweepEvent(c[0][1], false), true); + + tree.insert(DA); + tree.insert(DC); + + let begin = tree.minNode(); + expect(begin.key).toBe(DA); + + begin = tree.next(begin); + expect(begin.key).toBe(DC); + + begin = tree.next(begin); + expect(begin.key).toBe(EF); + + begin = tree.next(begin); + expect(begin.key).toBe(EG); + }); +}); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..ae45bf4 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "target": "ES2020", + "lib": ["ES2020"], + "module": "ESNext", + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "preserve", + + "strict": false, + "skipLibCheck": true, + + "declaration": true, + "outDir": "dist" + }, + "include": [ + "src/**/*", + "index.ts", + "test/**/*" + ], + "exclude": [ + "node_modules", + "dist", + "demo" + ] +} \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..88b8dfe --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,78 @@ +import { defineConfig } from "vite"; +import dts from "vite-plugin-dts"; +import { resolve } from "path"; +import { copyFileSync, mkdirSync, readdirSync, statSync } from "fs"; +import { join } from "path"; + +export default defineConfig(({ mode }) => { + const isDemo = mode === "demo"; + + if (isDemo) { + // Demo build configuration + return { + root: "demo", + base: "./", + build: { + outDir: "../dist/demo", + emptyOutDir: true, + rollupOptions: { + input: { + main: resolve(__dirname, "demo/index.html"), + orthogonal: resolve(__dirname, "demo/orthogonal.html"), + }, + }, + }, + plugins: [ + { + name: "copy-fixtures", + closeBundle() { + const fixturesSource = resolve(__dirname, "test/fixtures"); + const fixturesDest = resolve(__dirname, "dist/demo/fixtures"); + + // Create destination directory + mkdirSync(fixturesDest, { recursive: true }); + + // Copy all files from fixtures + const files = readdirSync(fixturesSource); + files.forEach(file => { + const sourcePath = join(fixturesSource, file); + const destPath = join(fixturesDest, file); + + if (statSync(sourcePath).isFile()) { + copyFileSync(sourcePath, destPath); + console.log(`Copied fixture: ${file}`); + } + }); + } + } + ] + }; + } + + // Library build configuration + return { + plugins: [ + dts({ + include: ["src/**/*", "index.ts"], + exclude: ["test/**/*", "demo/**/*", "bench/**/*"], + rollupTypes: true, + bundledPackages: ["robust-predicates", "splaytree", "tinyqueue"], + }), + ], + build: { + lib: { + entry: resolve(__dirname, "index.ts"), + name: "martinez", + formats: ["es", "cjs", "umd"], + fileName: (format) => { + if (format === "es") return "martinez.js"; + if (format === "cjs") return "martinez.cjs"; + return `martinez.${format}.js`; + }, + }, + rollupOptions: { + external: ["robust-predicates", "splaytree", "tinyqueue"], + }, + }, + }; +}); diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..ab822c1 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + globals: true, + environment: 'node', + include: ['test/**/*.test.ts'], + benchmark: { + include: ['bench/**/*.bench.ts'] + } + } +}); \ No newline at end of file