**/.DS_Store
/sdk.mk
/output/
+**/node_modules
include sdk.mk
-.PHONY: clean all osgi
+.PHONY: clean all osgi web
-all: osgi
+all: web osgi
install: osgi-install
org.argeo.app.api \
org.argeo.app.core \
org.argeo.app.jcr \
+org.argeo.app.geo \
org.argeo.app.servlet.odk \
org.argeo.app.servlet.publish \
org.argeo.app.theme.default \
org.argeo.app.profile.acr.fs \
org.argeo.app.profile.acr.jcr \
+org.argeo.suite.knowledge \
swt/org.argeo.app.swt \
+swt/org.argeo.app.geo.swt \
swt/org.argeo.app.ui \
-org.argeo.suite.knowledge \
DEP_CATEGORIES = \
org.argeo.tp \
clean:
rm -rf $(BUILD_BASE)
+ make -C js clean
+
+native-deps-debian:
+ sudo apt install npm
+
+## WEB
+web:
+ make -C js all
-include $(SDK_SRC_BASE)/sdk/argeo-build/osgi.mk
\ No newline at end of file
+include $(SDK_SRC_BASE)/sdk/argeo-build/osgi.mk
modified version without this exception; this exception also makes it possible
to release a modified version which carries forward this exception.
+# Apache License Permission
+
+Linking Argeo Suite statically or dynamically with other modules is making a
+combined work based on Argeo Suite. Thus, the terms and conditions of the GNU
+General Public License cover the whole combination when this license becomes
+applicable.
+
+In addition, as a special exception, the copyright holders of Argeo Suite give
+you permission to combine Argeo Suite with any program released under the
+terms and conditions of the Apache License v2.0 or any later version of this
+license. You may copy and distribute such a system following the terms of
+the GNU GPL for Argeo Suite and the licenses of the other code concerned,
+provided that you include the source code of that other code when and as
+the GNU GPL requires distribution of source code.
+
+Note that people who make modified versions of Argeo Suite are not obligated
+to grant this special exception for their modified versions; it is their choice
+whether to do so. The GNU General Public License gives permission to release a
+modified version without this exception; this exception also makes it possible
+to release a modified version which carries forward this exception.
+
# Java Content Repository API version 2.0 Permission
Linking Argeo Suite statically or dynamically with other modules is making a
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
+ <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${project}"/>
+ <booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="true"/>
+ <stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <resources> <item path="/argeo-suite-js/package-lock.json" type="1"/> <item path="/argeo-suite-js/package.json" type="1"/> <item path="/argeo-suite-js/src" type="2"/> <item path="/argeo-suite-js/webpack.common.js" type="1"/> <item path="/argeo-suite-js/webpack.dev.js" type="1"/> <item path="/argeo-suite-js/webpack.prod.js" type="1"/> </resources>}"/>
+ <stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="/usr/bin/npm"/>
+ <stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,"/>
+ <stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="run build"/>
+ <booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
+ <stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${project_loc:argeo-suite-js}"/>
+</launchConfiguration>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>argeo-suite-js</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
+ <triggers>auto,full,incremental,</triggers>
+ <arguments>
+ <dictionary>
+ <key>LaunchConfigHandle</key>
+ <value><project>/.externalToolBuilders/npm run build.launch</value>
+ </dictionary>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+</projectDescription>
--- /dev/null
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
--- /dev/null
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
--- /dev/null
+include ../sdk.mk
+
+A2_CATEGORY = org.argeo.suite
+
+BUNDLES = \
+org.argeo.app.js \
+
+all: npm-ci webpack osgi
+
+webpack:
+ npm run build-prod
+
+webpack-dev:
+ npm run build
+
+clean:
+ $(foreach bundle, $(BUNDLES), rm -rf $(bundle)/org)
+
+npm-ci:
+ npm ci
+
+npm-install:
+ npm install
+
+jsdoc:
+ node_modules/.bin/jsdoc -r src \
+ -d $(SDK_BUILD_BASE)/jsdoc/argeo-suite-js
+
+include $(SDK_SRC_BASE)/sdk/argeo-build/osgi.mk
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.app.js</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+Export-Package: \
+org.argeo.app.js,\
+
+
+Provide-Capability:\
+cms.publish;pkg=org.argeo.app.js;file="*.png,*.js,*.map,*.css,*.html",\
--- /dev/null
+bin.includes = META-INF/,\
+ org/
--- /dev/null
+{
+ "name": "org.argeo.app.js",
+ "version": "2.3.0.next",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "org.argeo.app.js",
+ "version": "2.3.0.next",
+ "license": "GPL",
+ "dependencies": {
+ "@nieuwlandgeo/sldreader": "0.3.x",
+ "chart.js": "4.x.x",
+ "chartjs-plugin-annotation": "^3.0.1",
+ "ol": "8.x.x"
+ },
+ "devDependencies": {
+ "css-loader": "^6.8.1",
+ "css-minimizer-webpack-plugin": "^5.0.1",
+ "html-webpack-plugin": "^5.5.3",
+ "jsdoc": "^4.0.2",
+ "mini-css-extract-plugin": "^2.7.6",
+ "npm-check-updates": "^16.13.2",
+ "style-loader": "^3.3.3",
+ "webpack": "^5.83.1",
+ "webpack-cli": "^5.1.1",
+ "webpack-merge": "^5.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
+ "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@colors/colors": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
+ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.1.90"
+ }
+ },
+ "node_modules/@discoveryjs/json-ext": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
+ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "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,
+ "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": ">=12"
+ }
+ },
+ "node_modules/@isaacs/cliui/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
+ },
+ "node_modules/@isaacs/cliui/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,
+ "dependencies": {
+ "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/@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,
+ "dependencies": {
+ "@sinclair/typebox": "^0.27.8"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/types": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
+ "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.6.3",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.8",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
+ "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
+ "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
+ "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@jsdoc/salty": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.5.tgz",
+ "integrity": "sha512-TfRP53RqunNe2HBobVBJ0VLhK1HbfvBYeTC1ahnN64PWvyYyGebmMiPkuwvD9fpw2ZbkoPb8Q7mwy0aR8Z9rvw==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.17.21"
+ },
+ "engines": {
+ "node": ">=v12.0.0"
+ }
+ },
+ "node_modules/@kurkle/color": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz",
+ "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
+ },
+ "node_modules/@nieuwlandgeo/sldreader": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@nieuwlandgeo/sldreader/-/sldreader-0.3.1.tgz",
+ "integrity": "sha512-gP1dw7ftVT34L6nv8dDtERNIJYENwe2I37Vwdm3NQH+KKHDk7vwrTANxvgKgbNybMXHF29jvI97Z/bkZYBqdxQ==",
+ "peerDependencies": {
+ "ol": ">= 5.3.0"
+ }
+ },
+ "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,
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "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,
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@npmcli/fs": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz",
+ "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/git": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-4.1.0.tgz",
+ "integrity": "sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/promise-spawn": "^6.0.0",
+ "lru-cache": "^7.4.4",
+ "npm-pick-manifest": "^8.0.0",
+ "proc-log": "^3.0.0",
+ "promise-inflight": "^1.0.1",
+ "promise-retry": "^2.0.1",
+ "semver": "^7.3.5",
+ "which": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/git/node_modules/which": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz",
+ "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/installed-package-contents": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz",
+ "integrity": "sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ==",
+ "dev": true,
+ "dependencies": {
+ "npm-bundled": "^3.0.0",
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "bin": {
+ "installed-package-contents": "lib/index.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/node-gyp": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz",
+ "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/promise-spawn": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz",
+ "integrity": "sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==",
+ "dev": true,
+ "dependencies": {
+ "which": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/promise-spawn/node_modules/which": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz",
+ "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/run-script": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-6.0.2.tgz",
+ "integrity": "sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/node-gyp": "^3.0.0",
+ "@npmcli/promise-spawn": "^6.0.0",
+ "node-gyp": "^9.0.0",
+ "read-package-json-fast": "^3.0.0",
+ "which": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@npmcli/run-script/node_modules/which": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz",
+ "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@petamoriken/float16": {
+ "version": "3.8.4",
+ "resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.8.4.tgz",
+ "integrity": "sha512-kB+NJ5Br56ZhElKsf0pM7/PQfrDdDVMRz8f0JM6eVOGE+L89z9hwcst9QvWBBnazzuqGTGtPsJNZoQ1JdNiGSQ=="
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@pnpm/config.env-replace": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz",
+ "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.22.0"
+ }
+ },
+ "node_modules/@pnpm/network.ca-file": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz",
+ "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "4.2.10"
+ },
+ "engines": {
+ "node": ">=12.22.0"
+ }
+ },
+ "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "dev": true
+ },
+ "node_modules/@pnpm/npm-conf": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz",
+ "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==",
+ "dev": true,
+ "dependencies": {
+ "@pnpm/config.env-replace": "^1.1.0",
+ "@pnpm/network.ca-file": "^1.0.1",
+ "config-chain": "^1.1.11"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@sigstore/bundle": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-1.1.0.tgz",
+ "integrity": "sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog==",
+ "dev": true,
+ "dependencies": {
+ "@sigstore/protobuf-specs": "^0.2.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@sigstore/protobuf-specs": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz",
+ "integrity": "sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@sigstore/sign": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-1.0.0.tgz",
+ "integrity": "sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA==",
+ "dev": true,
+ "dependencies": {
+ "@sigstore/bundle": "^1.1.0",
+ "@sigstore/protobuf-specs": "^0.2.0",
+ "make-fetch-happen": "^11.0.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@sigstore/tuf": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-1.0.3.tgz",
+ "integrity": "sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg==",
+ "dev": true,
+ "dependencies": {
+ "@sigstore/protobuf-specs": "^0.2.0",
+ "tuf-js": "^1.1.7"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "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
+ },
+ "node_modules/@sindresorhus/is": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz",
+ "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/is?sponsor=1"
+ }
+ },
+ "node_modules/@szmarczak/http-timer": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz",
+ "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==",
+ "dev": true,
+ "dependencies": {
+ "defer-to-connect": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=14.16"
+ }
+ },
+ "node_modules/@tootallnate/once": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
+ "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@trysound/sax": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
+ "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/@tufjs/canonical-json": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz",
+ "integrity": "sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@tufjs/models": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-1.0.4.tgz",
+ "integrity": "sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==",
+ "dev": true,
+ "dependencies": {
+ "@tufjs/canonical-json": "1.0.0",
+ "minimatch": "^9.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@types/eslint": {
+ "version": "8.44.3",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.3.tgz",
+ "integrity": "sha512-iM/WfkwAhwmPff3wZuPLYiHX18HI24jU8k1ZSH7P8FHwxTjZ2P6CoX2wnF43oprR+YXJM6UUxATkNvyv/JHd+g==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
+ }
+ },
+ "node_modules/@types/eslint-scope": {
+ "version": "3.7.5",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.5.tgz",
+ "integrity": "sha512-JNvhIEyxVW6EoMIFIvj93ZOywYFatlpu9deeH6eSx6PE3WHYvHaQtmHmQeNw7aA81bYGBPPQqdtBm6b1SsQMmA==",
+ "dev": true,
+ "dependencies": {
+ "@types/eslint": "*",
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.2.tgz",
+ "integrity": "sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==",
+ "dev": true
+ },
+ "node_modules/@types/html-minifier-terser": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
+ "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==",
+ "dev": true
+ },
+ "node_modules/@types/http-cache-semantics": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.2.tgz",
+ "integrity": "sha512-FD+nQWA2zJjh4L9+pFXqWOi0Hs1ryBCfI+985NjluQ1p8EYtoLvjLOKidXBtZ4/IcxDX4o8/E8qDS3540tNliw==",
+ "dev": true
+ },
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
+ "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
+ "dev": true
+ },
+ "node_modules/@types/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-gPQuzaPR5h/djlAv2apEG1HVOyj1IUs7GpfMZixU0/0KXT3pm64ylHuMUI1/Akh+sq/iikxg6Z2j+fcMDXaaTQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "node_modules/@types/istanbul-reports": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.2.tgz",
+ "integrity": "sha512-kv43F9eb3Lhj+lr/Hn6OcLCs/sSM8bt+fIaP11rCYngfV6NVjzWXJ17owQtDQTL9tQ8WSLUrGsSJ6rJz0F1w1A==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.13",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz",
+ "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==",
+ "dev": true
+ },
+ "node_modules/@types/linkify-it": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.3.tgz",
+ "integrity": "sha512-pTjcqY9E4nOI55Wgpz7eiI8+LzdYnw3qxXCfHyBDdPbYvbyLgWLJGh8EdPvqawwMK1Uo1794AUkkR38Fr0g+2g==",
+ "dev": true
+ },
+ "node_modules/@types/markdown-it": {
+ "version": "12.2.3",
+ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
+ "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/linkify-it": "*",
+ "@types/mdurl": "*"
+ }
+ },
+ "node_modules/@types/mdurl": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.3.tgz",
+ "integrity": "sha512-T5k6kTXak79gwmIOaDF2UUQXFbnBE0zBUzF20pz7wDYu0RQMzWg+Ml/Pz50214NsFHBITkoi5VtdjFZnJ2ijjA==",
+ "dev": true
+ },
+ "node_modules/@types/node": {
+ "version": "20.8.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.3.tgz",
+ "integrity": "sha512-jxiZQFpb+NlH5kjW49vXxvxTjeeqlbsnTAdBTKpzEdPs9itay7MscYXz3Fo9VYFEsfQ6LJFitHad3faerLAjCw==",
+ "dev": true
+ },
+ "node_modules/@types/yargs": {
+ "version": "17.0.28",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.28.tgz",
+ "integrity": "sha512-N3e3fkS86hNhtk6BEnc0rj3zcehaxx8QWhCROJkqpl5Zaoi7nAic3jH8q94jVD3zu5LGk+PUB6KAiDmimYOEQw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@types/yargs-parser": {
+ "version": "21.0.1",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.1.tgz",
+ "integrity": "sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/ast": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
+ "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/helper-numbers": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
+ "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-api-error": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
+ "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-buffer": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
+ "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-numbers": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
+ "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/floating-point-hex-parser": "1.11.6",
+ "@webassemblyjs/helper-api-error": "1.11.6",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
+ "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-wasm-section": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
+ "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/ieee754": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
+ "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
+ "dev": true,
+ "dependencies": {
+ "@xtuc/ieee754": "^1.2.0"
+ }
+ },
+ "node_modules/@webassemblyjs/leb128": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
+ "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
+ "dev": true,
+ "dependencies": {
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/utf8": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
+ "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/wasm-edit": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
+ "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/helper-wasm-section": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6",
+ "@webassemblyjs/wasm-opt": "1.11.6",
+ "@webassemblyjs/wasm-parser": "1.11.6",
+ "@webassemblyjs/wast-printer": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-gen": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
+ "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/ieee754": "1.11.6",
+ "@webassemblyjs/leb128": "1.11.6",
+ "@webassemblyjs/utf8": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-opt": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
+ "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6",
+ "@webassemblyjs/wasm-parser": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-parser": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
+ "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-api-error": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/ieee754": "1.11.6",
+ "@webassemblyjs/leb128": "1.11.6",
+ "@webassemblyjs/utf8": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/wast-printer": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
+ "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webpack-cli/configtest": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz",
+ "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ }
+ },
+ "node_modules/@webpack-cli/info": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz",
+ "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ }
+ },
+ "node_modules/@webpack-cli/serve": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz",
+ "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ },
+ "peerDependenciesMeta": {
+ "webpack-dev-server": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@xtuc/ieee754": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+ "dev": true
+ },
+ "node_modules/@xtuc/long": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+ "dev": true
+ },
+ "node_modules/abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "dev": true
+ },
+ "node_modules/acorn": {
+ "version": "8.10.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
+ "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-import-assertions": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
+ "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
+ "dev": true,
+ "peerDependencies": {
+ "acorn": "^8"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "dev": true,
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/agentkeepalive": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz",
+ "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==",
+ "dev": true,
+ "dependencies": {
+ "humanize-ms": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ }
+ },
+ "node_modules/aggregate-error": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+ "dev": true,
+ "dependencies": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "8.12.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
+ "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
+ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "node_modules/ansi-align": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
+ "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.1.0"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "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,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/aproba": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
+ "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
+ "dev": true
+ },
+ "node_modules/are-we-there-yet": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
+ "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
+ "dev": true,
+ "dependencies": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^3.6.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
+ "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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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
+ },
+ "node_modules/bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+ "dev": true
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true
+ },
+ "node_modules/boxen": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz",
+ "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==",
+ "dev": true,
+ "dependencies": {
+ "ansi-align": "^3.0.1",
+ "camelcase": "^7.0.1",
+ "chalk": "^5.2.0",
+ "cli-boxes": "^3.0.0",
+ "string-width": "^5.1.2",
+ "type-fest": "^2.13.0",
+ "widest-line": "^4.0.1",
+ "wrap-ansi": "^8.1.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/boxen/node_modules/chalk": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+ "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+ "dev": true,
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/boxen/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
+ },
+ "node_modules/boxen/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,
+ "dependencies": {
+ "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/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
+ "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001541",
+ "electron-to-chromium": "^1.4.535",
+ "node-releases": "^2.0.13",
+ "update-browserslist-db": "^1.0.13"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true
+ },
+ "node_modules/builtins": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz",
+ "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.0.0"
+ }
+ },
+ "node_modules/cacache": {
+ "version": "17.1.4",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.4.tgz",
+ "integrity": "sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/fs": "^3.1.0",
+ "fs-minipass": "^3.0.0",
+ "glob": "^10.2.2",
+ "lru-cache": "^7.7.1",
+ "minipass": "^7.0.3",
+ "minipass-collect": "^1.0.2",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "p-map": "^4.0.0",
+ "ssri": "^10.0.0",
+ "tar": "^6.1.11",
+ "unique-filename": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/cacache/node_modules/minipass": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
+ "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/cacheable-lookup": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz",
+ "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ }
+ },
+ "node_modules/cacheable-request": {
+ "version": "10.2.14",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz",
+ "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/http-cache-semantics": "^4.0.2",
+ "get-stream": "^6.0.1",
+ "http-cache-semantics": "^4.1.1",
+ "keyv": "^4.5.3",
+ "mimic-response": "^4.0.0",
+ "normalize-url": "^8.0.0",
+ "responselike": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ }
+ },
+ "node_modules/camel-case": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
+ "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
+ "dev": true,
+ "dependencies": {
+ "pascal-case": "^3.1.2",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz",
+ "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/caniuse-api": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
+ "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.0.0",
+ "caniuse-lite": "^1.0.0",
+ "lodash.memoize": "^4.1.2",
+ "lodash.uniq": "^4.5.0"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001546",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001546.tgz",
+ "integrity": "sha512-zvtSJwuQFpewSyRrI3AsftF6rM0X80mZkChIt1spBGEvRglCrjTniXvinc8JKRoqTwXAgvqTImaN9igfSMtUBw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ]
+ },
+ "node_modules/catharsis": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz",
+ "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.17.15"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "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"
+ }
+ },
+ "node_modules/chalk/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==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/chart.js": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.0.tgz",
+ "integrity": "sha512-vQEj6d+z0dcsKLlQvbKIMYFHd3t8W/7L2vfJIbYcfyPcRx92CsHqECpueN8qVGNlKyDcr5wBrYAYKnfu/9Q1hQ==",
+ "dependencies": {
+ "@kurkle/color": "^0.3.0"
+ },
+ "engines": {
+ "pnpm": ">=7"
+ }
+ },
+ "node_modules/chartjs-plugin-annotation": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/chartjs-plugin-annotation/-/chartjs-plugin-annotation-3.0.1.tgz",
+ "integrity": "sha512-hlIrXXKqSDgb+ZjVYHefmlZUXK8KbkCPiynSVrTb/HjTMkT62cOInaT1NTQCKtxKKOm9oHp958DY3RTAFKtkHg==",
+ "peerDependencies": {
+ "chart.js": ">=4.0.0"
+ }
+ },
+ "node_modules/chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/chrome-trace-event": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
+ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
+ "node_modules/ci-info": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
+ "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/clean-css": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz",
+ "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==",
+ "dev": true,
+ "dependencies": {
+ "source-map": "~0.6.0"
+ },
+ "engines": {
+ "node": ">= 10.0"
+ }
+ },
+ "node_modules/clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/cli-boxes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz",
+ "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-table3": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz",
+ "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0"
+ },
+ "engines": {
+ "node": "10.* || >= 12.*"
+ },
+ "optionalDependencies": {
+ "@colors/colors": "1.5.0"
+ }
+ },
+ "node_modules/clone-deep": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
+ "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+ "dev": true,
+ "dependencies": {
+ "is-plain-object": "^2.0.4",
+ "kind-of": "^6.0.2",
+ "shallow-clone": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "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/color-support": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+ "dev": true,
+ "bin": {
+ "color-support": "bin.js"
+ }
+ },
+ "node_modules/colord": {
+ "version": "2.9.3",
+ "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
+ "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
+ "dev": true
+ },
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "dev": true
+ },
+ "node_modules/commander": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+ "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+ "dev": true,
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "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
+ },
+ "node_modules/config-chain": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
+ "dev": true,
+ "dependencies": {
+ "ini": "^1.3.4",
+ "proto-list": "~1.2.1"
+ }
+ },
+ "node_modules/config-chain/node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true
+ },
+ "node_modules/configstore": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz",
+ "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==",
+ "dev": true,
+ "dependencies": {
+ "dot-prop": "^6.0.1",
+ "graceful-fs": "^4.2.6",
+ "unique-string": "^3.0.0",
+ "write-file-atomic": "^3.0.3",
+ "xdg-basedir": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/yeoman/configstore?sponsor=1"
+ }
+ },
+ "node_modules/console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
+ "dev": true
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/crypto-random-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz",
+ "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/crypto-random-string/node_modules/type-fest": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
+ "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/css-declaration-sorter": {
+ "version": "6.4.1",
+ "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz",
+ "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==",
+ "dev": true,
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.9"
+ }
+ },
+ "node_modules/css-loader": {
+ "version": "6.8.1",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz",
+ "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==",
+ "dev": true,
+ "dependencies": {
+ "icss-utils": "^5.1.0",
+ "postcss": "^8.4.21",
+ "postcss-modules-extract-imports": "^3.0.0",
+ "postcss-modules-local-by-default": "^4.0.3",
+ "postcss-modules-scope": "^3.0.0",
+ "postcss-modules-values": "^4.0.0",
+ "postcss-value-parser": "^4.2.0",
+ "semver": "^7.3.8"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.0.0"
+ }
+ },
+ "node_modules/css-minimizer-webpack-plugin": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz",
+ "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.18",
+ "cssnano": "^6.0.1",
+ "jest-worker": "^29.4.3",
+ "postcss": "^8.4.24",
+ "schema-utils": "^4.0.1",
+ "serialize-javascript": "^6.0.1"
+ },
+ "engines": {
+ "node": ">= 14.15.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@parcel/css": {
+ "optional": true
+ },
+ "@swc/css": {
+ "optional": true
+ },
+ "clean-css": {
+ "optional": true
+ },
+ "csso": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/css-select": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
+ "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
+ "dev": true,
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.0.1",
+ "domhandler": "^4.3.1",
+ "domutils": "^2.8.0",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-tree": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
+ "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
+ "dev": true,
+ "dependencies": {
+ "mdn-data": "2.0.30",
+ "source-map-js": "^1.0.1"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cssnano": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.0.1.tgz",
+ "integrity": "sha512-fVO1JdJ0LSdIGJq68eIxOqFpIJrZqXUsBt8fkrBcztCQqAjQD51OhZp7tc0ImcbwXD4k7ny84QTV90nZhmqbkg==",
+ "dev": true,
+ "dependencies": {
+ "cssnano-preset-default": "^6.0.1",
+ "lilconfig": "^2.1.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/cssnano"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/cssnano-preset-default": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.0.1.tgz",
+ "integrity": "sha512-7VzyFZ5zEB1+l1nToKyrRkuaJIx0zi/1npjvZfbBwbtNTzhLtlvYraK/7/uqmX2Wb2aQtd983uuGw79jAjLSuQ==",
+ "dev": true,
+ "dependencies": {
+ "css-declaration-sorter": "^6.3.1",
+ "cssnano-utils": "^4.0.0",
+ "postcss-calc": "^9.0.0",
+ "postcss-colormin": "^6.0.0",
+ "postcss-convert-values": "^6.0.0",
+ "postcss-discard-comments": "^6.0.0",
+ "postcss-discard-duplicates": "^6.0.0",
+ "postcss-discard-empty": "^6.0.0",
+ "postcss-discard-overridden": "^6.0.0",
+ "postcss-merge-longhand": "^6.0.0",
+ "postcss-merge-rules": "^6.0.1",
+ "postcss-minify-font-values": "^6.0.0",
+ "postcss-minify-gradients": "^6.0.0",
+ "postcss-minify-params": "^6.0.0",
+ "postcss-minify-selectors": "^6.0.0",
+ "postcss-normalize-charset": "^6.0.0",
+ "postcss-normalize-display-values": "^6.0.0",
+ "postcss-normalize-positions": "^6.0.0",
+ "postcss-normalize-repeat-style": "^6.0.0",
+ "postcss-normalize-string": "^6.0.0",
+ "postcss-normalize-timing-functions": "^6.0.0",
+ "postcss-normalize-unicode": "^6.0.0",
+ "postcss-normalize-url": "^6.0.0",
+ "postcss-normalize-whitespace": "^6.0.0",
+ "postcss-ordered-values": "^6.0.0",
+ "postcss-reduce-initial": "^6.0.0",
+ "postcss-reduce-transforms": "^6.0.0",
+ "postcss-svgo": "^6.0.0",
+ "postcss-unique-selectors": "^6.0.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/cssnano-utils": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.0.tgz",
+ "integrity": "sha512-Z39TLP+1E0KUcd7LGyF4qMfu8ZufI0rDzhdyAMsa/8UyNUU8wpS0fhdBxbQbv32r64ea00h4878gommRVg2BHw==",
+ "dev": true,
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/csso": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
+ "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
+ "dev": true,
+ "dependencies": {
+ "css-tree": "~2.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/csso/node_modules/css-tree": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz",
+ "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
+ "dev": true,
+ "dependencies": {
+ "mdn-data": "2.0.28",
+ "source-map-js": "^1.0.1"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/csso/node_modules/mdn-data": {
+ "version": "2.0.28",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz",
+ "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==",
+ "dev": true
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decompress-response": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+ "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+ "dev": true,
+ "dependencies": {
+ "mimic-response": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/decompress-response/node_modules/mimic-response": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/defer-to-connect": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
+ "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
+ "dev": true
+ },
+ "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,
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dom-converter": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
+ "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==",
+ "dev": true,
+ "dependencies": {
+ "utila": "~0.4"
+ }
+ },
+ "node_modules/dom-serializer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
+ "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
+ "dev": true,
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.2.0",
+ "entities": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ]
+ },
+ "node_modules/domhandler": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
+ "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
+ "dev": true,
+ "dependencies": {
+ "domelementtype": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
+ "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+ "dev": true,
+ "dependencies": {
+ "dom-serializer": "^1.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/dot-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
+ "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
+ "dev": true,
+ "dependencies": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/dot-prop": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
+ "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==",
+ "dev": true,
+ "dependencies": {
+ "is-obj": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/earcut": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz",
+ "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ=="
+ },
+ "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
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.544",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.544.tgz",
+ "integrity": "sha512-54z7squS1FyFRSUqq/knOFSptjjogLZXbKcYk3B0qkE1KZzvqASwRZnY2KzZQJqIYLVD38XZeoiMRflYSwyO4w==",
+ "dev": true
+ },
+ "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/encoding": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+ "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "iconv-lite": "^0.6.2"
+ }
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.15.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
+ "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
+ "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/envinfo": {
+ "version": "7.10.0",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz",
+ "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==",
+ "dev": true,
+ "bin": {
+ "envinfo": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/err-code": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
+ "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
+ "dev": true
+ },
+ "node_modules/es-module-lexer": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz",
+ "integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==",
+ "dev": true
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-goat": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz",
+ "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "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"
+ }
+ },
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "node_modules/exponential-backoff": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz",
+ "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==",
+ "dev": true
+ },
+ "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-glob": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz",
+ "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==",
+ "dev": true,
+ "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.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "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/fast-memoize": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz",
+ "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==",
+ "dev": true
+ },
+ "node_modules/fastest-levenshtein": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4.9.1"
+ }
+ },
+ "node_modules/fastq": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
+ "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
+ "dev": true,
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/foreground-child": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
+ "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/form-data-encoder": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz",
+ "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 14.17"
+ }
+ },
+ "node_modules/fp-and-or": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/fp-and-or/-/fp-and-or-0.1.4.tgz",
+ "integrity": "sha512-+yRYRhpnFPWXSly/6V4Lw9IfOV26uu30kynGJ03PW+MnjOEQe45RZ141QcS0aJehYBYA50GfCDnsRbFJdhssRw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/fs-minipass": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz",
+ "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/fs-minipass/node_modules/minipass": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
+ "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "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/gauge": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
+ "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
+ "dev": true,
+ "dependencies": {
+ "aproba": "^1.0.3 || ^2.0.0",
+ "color-support": "^1.1.3",
+ "console-control-strings": "^1.1.0",
+ "has-unicode": "^2.0.1",
+ "signal-exit": "^3.0.7",
+ "string-width": "^4.2.3",
+ "strip-ansi": "^6.0.1",
+ "wide-align": "^1.1.5"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/gauge/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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/gauge/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/gauge/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,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/geotiff": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/geotiff/-/geotiff-2.0.7.tgz",
+ "integrity": "sha512-FKvFTNowMU5K6lHYY2f83d4lS2rsCNdpUC28AX61x9ZzzqPNaWFElWv93xj0eJFaNyOYA63ic5OzJ88dHpoA5Q==",
+ "dependencies": {
+ "@petamoriken/float16": "^3.4.7",
+ "lerc": "^3.0.0",
+ "pako": "^2.0.4",
+ "parse-headers": "^2.0.2",
+ "quick-lru": "^6.1.1",
+ "web-worker": "^1.2.0",
+ "xml-utils": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=10.19"
+ }
+ },
+ "node_modules/get-stdin": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
+ "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/glob": {
+ "version": "10.3.10",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
+ "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
+ "dev": true,
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^2.3.5",
+ "minimatch": "^9.0.1",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
+ "path-scurry": "^1.10.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "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,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "dev": true
+ },
+ "node_modules/global-dirs": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz",
+ "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==",
+ "dev": true,
+ "dependencies": {
+ "ini": "2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/global-dirs/node_modules/ini": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz",
+ "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "dependencies": {
+ "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": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/got": {
+ "version": "12.6.1",
+ "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz",
+ "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==",
+ "dev": true,
+ "dependencies": {
+ "@sindresorhus/is": "^5.2.0",
+ "@szmarczak/http-timer": "^5.0.1",
+ "cacheable-lookup": "^7.0.0",
+ "cacheable-request": "^10.2.8",
+ "decompress-response": "^6.0.0",
+ "form-data-encoder": "^2.1.2",
+ "get-stream": "^6.0.1",
+ "http2-wrapper": "^2.1.10",
+ "lowercase-keys": "^3.0.0",
+ "p-cancelable": "^3.0.0",
+ "responselike": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/got?sponsor=1"
+ }
+ },
+ "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
+ },
+ "node_modules/has": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz",
+ "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-unicode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
+ "dev": true
+ },
+ "node_modules/has-yarn": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz",
+ "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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,
+ "bin": {
+ "he": "bin/he"
+ }
+ },
+ "node_modules/hosted-git-info": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz",
+ "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^7.5.1"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/html-minifier-terser": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
+ "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==",
+ "dev": true,
+ "dependencies": {
+ "camel-case": "^4.1.2",
+ "clean-css": "^5.2.2",
+ "commander": "^8.3.0",
+ "he": "^1.2.0",
+ "param-case": "^3.0.4",
+ "relateurl": "^0.2.7",
+ "terser": "^5.10.0"
+ },
+ "bin": {
+ "html-minifier-terser": "cli.js"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/html-webpack-plugin": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz",
+ "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==",
+ "dev": true,
+ "dependencies": {
+ "@types/html-minifier-terser": "^6.0.0",
+ "html-minifier-terser": "^6.0.2",
+ "lodash": "^4.17.21",
+ "pretty-error": "^4.0.0",
+ "tapable": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/html-webpack-plugin"
+ },
+ "peerDependencies": {
+ "webpack": "^5.20.0"
+ }
+ },
+ "node_modules/htmlparser2": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
+ "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
+ "dev": true,
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.0.0",
+ "domutils": "^2.5.2",
+ "entities": "^2.0.0"
+ }
+ },
+ "node_modules/http-cache-semantics": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
+ "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
+ "dev": true
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
+ "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
+ "dev": true,
+ "dependencies": {
+ "@tootallnate/once": "2",
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/http2-wrapper": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz",
+ "integrity": "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==",
+ "dev": true,
+ "dependencies": {
+ "quick-lru": "^5.1.1",
+ "resolve-alpn": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=10.19.0"
+ }
+ },
+ "node_modules/http2-wrapper/node_modules/quick-lru": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
+ "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/humanize-ms": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
+ "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.0.0"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/icss-utils": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
+ "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
+ "dev": true,
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/ignore": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/ignore-walk": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.3.tgz",
+ "integrity": "sha512-C7FfFoTA+bI10qfeydT8aZbvr91vAEU+2W5BZUlzPec47oNb07SsOfwYrtxuvOYdUApPP/Qlh4DtAO51Ekk2QA==",
+ "dev": true,
+ "dependencies": {
+ "minimatch": "^9.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/import-local": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+ "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
+ "dev": true,
+ "dependencies": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ },
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "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/ini": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz",
+ "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/interpret": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
+ "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/ip": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
+ "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==",
+ "dev": true
+ },
+ "node_modules/is-ci": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
+ "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==",
+ "dev": true,
+ "dependencies": {
+ "ci-info": "^3.2.0"
+ },
+ "bin": {
+ "is-ci": "bin.js"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.13.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz",
+ "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=0.10.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==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-installed-globally": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz",
+ "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==",
+ "dev": true,
+ "dependencies": {
+ "global-dirs": "^3.0.0",
+ "is-path-inside": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-lambda": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
+ "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
+ "dev": true
+ },
+ "node_modules/is-npm": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz",
+ "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
+ "dev": true
+ },
+ "node_modules/is-yarn-global": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz",
+ "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "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/isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/jackspeak": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
+ "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
+ "dev": true,
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/jest-util": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
+ "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "graceful-fs": "^4.2.9",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-worker": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz",
+ "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "jest-util": "^29.7.0",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "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
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/js2xmlparser": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz",
+ "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==",
+ "dev": true,
+ "dependencies": {
+ "xmlcreate": "^2.0.4"
+ }
+ },
+ "node_modules/jsdoc": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz",
+ "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.20.15",
+ "@jsdoc/salty": "^0.2.1",
+ "@types/markdown-it": "^12.2.3",
+ "bluebird": "^3.7.2",
+ "catharsis": "^0.9.0",
+ "escape-string-regexp": "^2.0.0",
+ "js2xmlparser": "^4.0.2",
+ "klaw": "^3.0.0",
+ "markdown-it": "^12.3.2",
+ "markdown-it-anchor": "^8.4.1",
+ "marked": "^4.0.10",
+ "mkdirp": "^1.0.4",
+ "requizzle": "^0.2.3",
+ "strip-json-comments": "^3.1.0",
+ "underscore": "~1.13.2"
+ },
+ "bin": {
+ "jsdoc": "jsdoc.js"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz",
+ "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/json-parse-helpfulerror": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz",
+ "integrity": "sha512-XgP0FGR77+QhUxjXkwOMkC94k3WtqEBfcnjWqhRd82qTat4SWKRE+9kUnynz/shm3I4ea2+qISvTIeGTNU7kJg==",
+ "dev": true,
+ "dependencies": {
+ "jju": "^1.1.0"
+ }
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jsonlines": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsonlines/-/jsonlines-0.1.1.tgz",
+ "integrity": "sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA==",
+ "dev": true
+ },
+ "node_modules/jsonparse": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
+ "dev": true,
+ "engines": [
+ "node >= 0.2.0"
+ ]
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/klaw": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz",
+ "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.9"
+ }
+ },
+ "node_modules/kleur": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
+ "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/latest-version": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz",
+ "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==",
+ "dev": true,
+ "dependencies": {
+ "package-json": "^8.1.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lerc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/lerc/-/lerc-3.0.0.tgz",
+ "integrity": "sha512-Rm4J/WaHhRa93nCN2mwWDZFoRVF18G1f47C+kvQWyHGEZxFpTUi73p7lMVSAndyxGt6lJ2/CFbOcf9ra5p8aww=="
+ },
+ "node_modules/lilconfig": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
+ "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/linkify-it": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
+ "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
+ "dev": true,
+ "dependencies": {
+ "uc.micro": "^1.0.1"
+ }
+ },
+ "node_modules/loader-runner": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
+ "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.11.5"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "node_modules/lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
+ "dev": true
+ },
+ "node_modules/lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
+ "dev": true
+ },
+ "node_modules/lower-case": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
+ "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
+ "dev": true,
+ "dependencies": {
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/lowercase-keys": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz",
+ "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/make-fetch-happen": {
+ "version": "11.1.1",
+ "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz",
+ "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==",
+ "dev": true,
+ "dependencies": {
+ "agentkeepalive": "^4.2.1",
+ "cacache": "^17.0.0",
+ "http-cache-semantics": "^4.1.1",
+ "http-proxy-agent": "^5.0.0",
+ "https-proxy-agent": "^5.0.0",
+ "is-lambda": "^1.0.1",
+ "lru-cache": "^7.7.1",
+ "minipass": "^5.0.0",
+ "minipass-fetch": "^3.0.0",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "negotiator": "^0.6.3",
+ "promise-retry": "^2.0.1",
+ "socks-proxy-agent": "^7.0.0",
+ "ssri": "^10.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/markdown-it": {
+ "version": "12.3.2",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
+ "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^2.0.1",
+ "entities": "~2.1.0",
+ "linkify-it": "^3.0.1",
+ "mdurl": "^1.0.1",
+ "uc.micro": "^1.0.5"
+ },
+ "bin": {
+ "markdown-it": "bin/markdown-it.js"
+ }
+ },
+ "node_modules/markdown-it-anchor": {
+ "version": "8.6.7",
+ "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz",
+ "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==",
+ "dev": true,
+ "peerDependencies": {
+ "@types/markdown-it": "*",
+ "markdown-it": "*"
+ }
+ },
+ "node_modules/marked": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
+ "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
+ "dev": true,
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/mdn-data": {
+ "version": "2.0.30",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
+ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
+ "dev": true
+ },
+ "node_modules/mdurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+ "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==",
+ "dev": true
+ },
+ "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
+ },
+ "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,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-response": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz",
+ "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mini-css-extract-plugin": {
+ "version": "2.7.6",
+ "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz",
+ "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==",
+ "dev": true,
+ "dependencies": {
+ "schema-utils": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.0.0"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-collect": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
+ "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/minipass-collect/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-fetch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz",
+ "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^7.0.3",
+ "minipass-sized": "^1.0.3",
+ "minizlib": "^2.1.2"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ },
+ "optionalDependencies": {
+ "encoding": "^0.1.13"
+ }
+ },
+ "node_modules/minipass-fetch/node_modules/minipass": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
+ "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/minipass-flush": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+ "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/minipass-flush/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-json-stream": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz",
+ "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==",
+ "dev": true,
+ "dependencies": {
+ "jsonparse": "^1.3.1",
+ "minipass": "^3.0.0"
+ }
+ },
+ "node_modules/minipass-json-stream/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-pipeline": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
+ "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-pipeline/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-sized": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
+ "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-sized/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/minizlib/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "dev": true,
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
+ "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true
+ },
+ "node_modules/no-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
+ "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
+ "dev": true,
+ "dependencies": {
+ "lower-case": "^2.0.2",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/node-gyp": {
+ "version": "9.4.0",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.0.tgz",
+ "integrity": "sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg==",
+ "dev": true,
+ "dependencies": {
+ "env-paths": "^2.2.0",
+ "exponential-backoff": "^3.1.1",
+ "glob": "^7.1.4",
+ "graceful-fs": "^4.2.6",
+ "make-fetch-happen": "^11.0.3",
+ "nopt": "^6.0.0",
+ "npmlog": "^6.0.0",
+ "rimraf": "^3.0.2",
+ "semver": "^7.3.5",
+ "tar": "^6.1.2",
+ "which": "^2.0.2"
+ },
+ "bin": {
+ "node-gyp": "bin/node-gyp.js"
+ },
+ "engines": {
+ "node": "^12.13 || ^14.13 || >=16"
+ }
+ },
+ "node_modules/node-gyp/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/node-gyp/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "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"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/node-gyp/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/node-gyp/node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.13",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
+ "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
+ "dev": true
+ },
+ "node_modules/nopt": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz",
+ "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==",
+ "dev": true,
+ "dependencies": {
+ "abbrev": "^1.0.0"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/normalize-package-data": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz",
+ "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==",
+ "dev": true,
+ "dependencies": {
+ "hosted-git-info": "^6.0.0",
+ "is-core-module": "^2.8.1",
+ "semver": "^7.3.5",
+ "validate-npm-package-license": "^3.0.4"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/normalize-package-data/node_modules/hosted-git-info": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz",
+ "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^7.5.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/normalize-url": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz",
+ "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm-bundled": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.0.tgz",
+ "integrity": "sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==",
+ "dev": true,
+ "dependencies": {
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-check-updates": {
+ "version": "16.14.5",
+ "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-16.14.5.tgz",
+ "integrity": "sha512-f7v3YzPUgadtkB2LAVhiWMjrSejJ0N8OM9JjjVfxBz2neHqmPSWQUAUA+U/p3xeXHl9bghRD6knRqBhm9dkRGg==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^5.3.0",
+ "cli-table3": "^0.6.3",
+ "commander": "^10.0.1",
+ "fast-memoize": "^2.5.2",
+ "find-up": "5.0.0",
+ "fp-and-or": "^0.1.3",
+ "get-stdin": "^8.0.0",
+ "globby": "^11.0.4",
+ "hosted-git-info": "^5.1.0",
+ "ini": "^4.1.1",
+ "js-yaml": "^4.1.0",
+ "json-parse-helpfulerror": "^1.0.3",
+ "jsonlines": "^0.1.1",
+ "lodash": "^4.17.21",
+ "make-fetch-happen": "^11.1.1",
+ "minimatch": "^9.0.3",
+ "p-map": "^4.0.0",
+ "pacote": "15.2.0",
+ "parse-github-url": "^1.0.2",
+ "progress": "^2.0.3",
+ "prompts-ncu": "^3.0.0",
+ "rc-config-loader": "^4.1.3",
+ "remote-git-tags": "^3.0.0",
+ "rimraf": "^5.0.1",
+ "semver": "^7.5.4",
+ "semver-utils": "^1.1.4",
+ "source-map-support": "^0.5.21",
+ "spawn-please": "^2.0.1",
+ "strip-ansi": "^7.1.0",
+ "strip-json-comments": "^5.0.1",
+ "untildify": "^4.0.0",
+ "update-notifier": "^6.0.2"
+ },
+ "bin": {
+ "ncu": "build/src/bin/cli.js",
+ "npm-check-updates": "build/src/bin/cli.js"
+ },
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "node_modules/npm-check-updates/node_modules/chalk": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+ "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+ "dev": true,
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/npm-check-updates/node_modules/commander": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/npm-check-updates/node_modules/strip-json-comments": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz",
+ "integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm-install-checks": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz",
+ "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.1.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-normalize-package-bin": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz",
+ "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-package-arg": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz",
+ "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==",
+ "dev": true,
+ "dependencies": {
+ "hosted-git-info": "^6.0.0",
+ "proc-log": "^3.0.0",
+ "semver": "^7.3.5",
+ "validate-npm-package-name": "^5.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-package-arg/node_modules/hosted-git-info": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz",
+ "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^7.5.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-packlist": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz",
+ "integrity": "sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==",
+ "dev": true,
+ "dependencies": {
+ "ignore-walk": "^6.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-pick-manifest": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz",
+ "integrity": "sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==",
+ "dev": true,
+ "dependencies": {
+ "npm-install-checks": "^6.0.0",
+ "npm-normalize-package-bin": "^3.0.0",
+ "npm-package-arg": "^10.0.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-registry-fetch": {
+ "version": "14.0.5",
+ "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz",
+ "integrity": "sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==",
+ "dev": true,
+ "dependencies": {
+ "make-fetch-happen": "^11.0.0",
+ "minipass": "^5.0.0",
+ "minipass-fetch": "^3.0.0",
+ "minipass-json-stream": "^1.0.1",
+ "minizlib": "^2.1.2",
+ "npm-package-arg": "^10.0.0",
+ "proc-log": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npmlog": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
+ "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
+ "dev": true,
+ "dependencies": {
+ "are-we-there-yet": "^3.0.0",
+ "console-control-strings": "^1.1.0",
+ "gauge": "^4.0.3",
+ "set-blocking": "^2.0.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/ol": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/ol/-/ol-8.1.0.tgz",
+ "integrity": "sha512-cx3SH2plpFS9fM8pp1nCypgQXGJD7Mcb1E3mEySmy5XEw1DUEo+kkNzgtAZz5qupekqi7aU9iBJEjCoMfqvO2Q==",
+ "dependencies": {
+ "earcut": "^2.2.3",
+ "geotiff": "^2.0.7",
+ "pbf": "3.2.1",
+ "rbush": "^3.0.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/openlayers"
+ }
+ },
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/p-cancelable": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz",
+ "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.20"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-map": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+ "dev": true,
+ "dependencies": {
+ "aggregate-error": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/package-json": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz",
+ "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==",
+ "dev": true,
+ "dependencies": {
+ "got": "^12.1.0",
+ "registry-auth-token": "^5.0.1",
+ "registry-url": "^6.0.0",
+ "semver": "^7.3.7"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pacote": {
+ "version": "15.2.0",
+ "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.2.0.tgz",
+ "integrity": "sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==",
+ "dev": true,
+ "dependencies": {
+ "@npmcli/git": "^4.0.0",
+ "@npmcli/installed-package-contents": "^2.0.1",
+ "@npmcli/promise-spawn": "^6.0.1",
+ "@npmcli/run-script": "^6.0.0",
+ "cacache": "^17.0.0",
+ "fs-minipass": "^3.0.0",
+ "minipass": "^5.0.0",
+ "npm-package-arg": "^10.0.0",
+ "npm-packlist": "^7.0.0",
+ "npm-pick-manifest": "^8.0.0",
+ "npm-registry-fetch": "^14.0.0",
+ "proc-log": "^3.0.0",
+ "promise-retry": "^2.0.1",
+ "read-package-json": "^6.0.0",
+ "read-package-json-fast": "^3.0.0",
+ "sigstore": "^1.3.0",
+ "ssri": "^10.0.0",
+ "tar": "^6.1.11"
+ },
+ "bin": {
+ "pacote": "lib/bin.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/pako": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
+ "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
+ },
+ "node_modules/param-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
+ "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
+ "dev": true,
+ "dependencies": {
+ "dot-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/parse-github-url": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz",
+ "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==",
+ "dev": true,
+ "bin": {
+ "parse-github-url": "cli.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/parse-headers": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz",
+ "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA=="
+ },
+ "node_modules/pascal-case": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
+ "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
+ "dev": true,
+ "dependencies": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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
+ },
+ "node_modules/path-scurry": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
+ "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^9.1.1 || ^10.0.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz",
+ "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==",
+ "dev": true,
+ "engines": {
+ "node": "14 || >=16.14"
+ }
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pbf": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz",
+ "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==",
+ "dependencies": {
+ "ieee754": "^1.1.12",
+ "resolve-protobuf-schema": "^2.1.0"
+ },
+ "bin": {
+ "pbf": "bin/pbf"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "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,
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/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,
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/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,
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/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,
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pkg-dir/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,
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.4.31",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+ "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+ "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"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.6",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-calc": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz",
+ "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.11",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.2"
+ }
+ },
+ "node_modules/postcss-colormin": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.0.0.tgz",
+ "integrity": "sha512-EuO+bAUmutWoZYgHn2T1dG1pPqHU6L4TjzPlu4t1wZGXQ/fxV16xg2EJmYi0z+6r+MGV1yvpx1BHkUaRrPa2bw==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.21.4",
+ "caniuse-api": "^3.0.0",
+ "colord": "^2.9.1",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-convert-values": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.0.0.tgz",
+ "integrity": "sha512-U5D8QhVwqT++ecmy8rnTb+RL9n/B806UVaS3m60lqle4YDFcpbS3ae5bTQIh3wOGUSDHSEtMYLs/38dNG7EYFw==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.21.4",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-discard-comments": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.0.tgz",
+ "integrity": "sha512-p2skSGqzPMZkEQvJsgnkBhCn8gI7NzRH2683EEjrIkoMiwRELx68yoUJ3q3DGSGuQ8Ug9Gsn+OuDr46yfO+eFw==",
+ "dev": true,
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-discard-duplicates": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.0.tgz",
+ "integrity": "sha512-bU1SXIizMLtDW4oSsi5C/xHKbhLlhek/0/yCnoMQany9k3nPBq+Ctsv/9oMmyqbR96HYHxZcHyK2HR5P/mqoGA==",
+ "dev": true,
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-discard-empty": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.0.tgz",
+ "integrity": "sha512-b+h1S1VT6dNhpcg+LpyiUrdnEZfICF0my7HAKgJixJLW7BnNmpRH34+uw/etf5AhOlIhIAuXApSzzDzMI9K/gQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-discard-overridden": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.0.tgz",
+ "integrity": "sha512-4VELwssYXDFigPYAZ8vL4yX4mUepF/oCBeeIT4OXsJPYOtvJumyz9WflmJWTfDwCUcpDR+z0zvCWBXgTx35SVw==",
+ "dev": true,
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-merge-longhand": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.0.tgz",
+ "integrity": "sha512-4VSfd1lvGkLTLYcxFuISDtWUfFS4zXe0FpF149AyziftPFQIWxjvFSKhA4MIxMe4XM3yTDgQMbSNgzIVxChbIg==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0",
+ "stylehacks": "^6.0.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-merge-rules": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.0.1.tgz",
+ "integrity": "sha512-a4tlmJIQo9SCjcfiCcCMg/ZCEe0XTkl/xK0XHBs955GWg9xDX3NwP9pwZ78QUOWB8/0XCjZeJn98Dae0zg6AAw==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.21.4",
+ "caniuse-api": "^3.0.0",
+ "cssnano-utils": "^4.0.0",
+ "postcss-selector-parser": "^6.0.5"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-minify-font-values": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.0.0.tgz",
+ "integrity": "sha512-zNRAVtyh5E8ndZEYXA4WS8ZYsAp798HiIQ1V2UF/C/munLp2r1UGHwf1+6JFu7hdEhJFN+W1WJQKBrtjhFgEnA==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-minify-gradients": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.0.tgz",
+ "integrity": "sha512-wO0F6YfVAR+K1xVxF53ueZJza3L+R3E6cp0VwuXJQejnNUH0DjcAFe3JEBeTY1dLwGa0NlDWueCA1VlEfiKgAA==",
+ "dev": true,
+ "dependencies": {
+ "colord": "^2.9.1",
+ "cssnano-utils": "^4.0.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-minify-params": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.0.0.tgz",
+ "integrity": "sha512-Fz/wMQDveiS0n5JPcvsMeyNXOIMrwF88n7196puSuQSWSa+/Ofc1gDOSY2xi8+A4PqB5dlYCKk/WfqKqsI+ReQ==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.21.4",
+ "cssnano-utils": "^4.0.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-minify-selectors": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.0.tgz",
+ "integrity": "sha512-ec/q9JNCOC2CRDNnypipGfOhbYPuUkewGwLnbv6omue/PSASbHSU7s6uSQ0tcFRVv731oMIx8k0SP4ZX6be/0g==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.5"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-modules-extract-imports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
+ "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
+ "dev": true,
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-modules-local-by-default": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz",
+ "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==",
+ "dev": true,
+ "dependencies": {
+ "icss-utils": "^5.0.0",
+ "postcss-selector-parser": "^6.0.2",
+ "postcss-value-parser": "^4.1.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-modules-scope": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz",
+ "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.4"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-modules-values": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
+ "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
+ "dev": true,
+ "dependencies": {
+ "icss-utils": "^5.0.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-normalize-charset": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.0.tgz",
+ "integrity": "sha512-cqundwChbu8yO/gSWkuFDmKrCZ2vJzDAocheT2JTd0sFNA4HMGoKMfbk2B+J0OmO0t5GUkiAkSM5yF2rSLUjgQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-display-values": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.0.tgz",
+ "integrity": "sha512-Qyt5kMrvy7dJRO3OjF7zkotGfuYALETZE+4lk66sziWSPzlBEt7FrUshV6VLECkI4EN8Z863O6Nci4NXQGNzYw==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-positions": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.0.tgz",
+ "integrity": "sha512-mPCzhSV8+30FZyWhxi6UoVRYd3ZBJgTRly4hOkaSifo0H+pjDYcii/aVT4YE6QpOil15a5uiv6ftnY3rm0igPg==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-repeat-style": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.0.tgz",
+ "integrity": "sha512-50W5JWEBiOOAez2AKBh4kRFm2uhrT3O1Uwdxz7k24aKtbD83vqmcVG7zoIwo6xI2FZ/HDlbrCopXhLeTpQib1A==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-string": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.0.tgz",
+ "integrity": "sha512-KWkIB7TrPOiqb8ZZz6homet2KWKJwIlysF5ICPZrXAylGe2hzX/HSf4NTX2rRPJMAtlRsj/yfkrWGavFuB+c0w==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-timing-functions": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.0.tgz",
+ "integrity": "sha512-tpIXWciXBp5CiFs8sem90IWlw76FV4oi6QEWfQwyeREVwUy39VSeSqjAT7X0Qw650yAimYW5gkl2Gd871N5SQg==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-unicode": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.0.0.tgz",
+ "integrity": "sha512-ui5crYkb5ubEUDugDc786L/Me+DXp2dLg3fVJbqyAl0VPkAeALyAijF2zOsnZyaS1HyfPuMH0DwyY18VMFVNkg==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.21.4",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-url": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.0.tgz",
+ "integrity": "sha512-98mvh2QzIPbb02YDIrYvAg4OUzGH7s1ZgHlD3fIdTHLgPLRpv1ZTKJDnSAKr4Rt21ZQFzwhGMXxpXlfrUBKFHw==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-whitespace": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.0.tgz",
+ "integrity": "sha512-7cfE1AyLiK0+ZBG6FmLziJzqQCpTQY+8XjMhMAz8WSBSCsCNNUKujgIgjCAmDT3cJ+3zjTXFkoD15ZPsckArVw==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-ordered-values": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.0.tgz",
+ "integrity": "sha512-K36XzUDpvfG/nWkjs6d1hRBydeIxGpKS2+n+ywlKPzx1nMYDYpoGbcjhj5AwVYJK1qV2/SDoDEnHzlPD6s3nMg==",
+ "dev": true,
+ "dependencies": {
+ "cssnano-utils": "^4.0.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-reduce-initial": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.0.0.tgz",
+ "integrity": "sha512-s2UOnidpVuXu6JiiI5U+fV2jamAw5YNA9Fdi/GRK0zLDLCfXmSGqQtzpUPtfN66RtCbb9fFHoyZdQaxOB3WxVA==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.21.4",
+ "caniuse-api": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-reduce-transforms": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.0.tgz",
+ "integrity": "sha512-FQ9f6xM1homnuy1wLe9lP1wujzxnwt1EwiigtWwuyf8FsqqXUDUp2Ulxf9A5yjlUOTdCJO6lonYjg1mgqIIi2w==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz",
+ "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==",
+ "dev": true,
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-svgo": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.0.tgz",
+ "integrity": "sha512-r9zvj/wGAoAIodn84dR/kFqwhINp5YsJkLoujybWG59grR/IHx+uQ2Zo+IcOwM0jskfYX3R0mo+1Kip1VSNcvw==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0",
+ "svgo": "^3.0.2"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >= 18"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-unique-selectors": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.0.tgz",
+ "integrity": "sha512-EPQzpZNxOxP7777t73RQpZE5e9TrnCrkvp7AH7a0l89JmZiPnS82y216JowHXwpBCQitfyxrof9TK3rYbi7/Yw==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.5"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "dev": true
+ },
+ "node_modules/pretty-error": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz",
+ "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.17.20",
+ "renderkid": "^3.0.0"
+ }
+ },
+ "node_modules/proc-log": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz",
+ "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "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/promise-inflight": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+ "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
+ "dev": true
+ },
+ "node_modules/promise-retry": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
+ "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
+ "dev": true,
+ "dependencies": {
+ "err-code": "^2.0.2",
+ "retry": "^0.12.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/prompts-ncu": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/prompts-ncu/-/prompts-ncu-3.0.0.tgz",
+ "integrity": "sha512-qyz9UxZ5MlPKWVhWrCmSZ1ahm2GVYdjLb8og2sg0IPth1KRuhcggHGuijz0e41dkx35p1t1q3GRISGH7QGALFA==",
+ "dev": true,
+ "dependencies": {
+ "kleur": "^4.0.1",
+ "sisteransi": "^1.0.5"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/proto-list": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
+ "dev": true
+ },
+ "node_modules/protocol-buffers-schema": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz",
+ "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw=="
+ },
+ "node_modules/punycode": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
+ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pupa": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz",
+ "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==",
+ "dev": true,
+ "dependencies": {
+ "escape-goat": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/quick-lru": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.2.tgz",
+ "integrity": "sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/quickselect": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
+ "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw=="
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/rbush": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/rbush/-/rbush-3.0.1.tgz",
+ "integrity": "sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==",
+ "dependencies": {
+ "quickselect": "^2.0.0"
+ }
+ },
+ "node_modules/rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "dev": true,
+ "dependencies": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "bin": {
+ "rc": "cli.js"
+ }
+ },
+ "node_modules/rc-config-loader": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/rc-config-loader/-/rc-config-loader-4.1.3.tgz",
+ "integrity": "sha512-kD7FqML7l800i6pS6pvLyIE2ncbk9Du8Q0gp/4hMPhJU6ZxApkoLcGD8ZeqgiAlfwZ6BlETq6qqe+12DUL207w==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.3.4",
+ "js-yaml": "^4.1.0",
+ "json5": "^2.2.2",
+ "require-from-string": "^2.0.2"
+ }
+ },
+ "node_modules/rc/node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true
+ },
+ "node_modules/rc/node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/read-package-json": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.4.tgz",
+ "integrity": "sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^10.2.2",
+ "json-parse-even-better-errors": "^3.0.0",
+ "normalize-package-data": "^5.0.0",
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/read-package-json-fast": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz",
+ "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==",
+ "dev": true,
+ "dependencies": {
+ "json-parse-even-better-errors": "^3.0.0",
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/rechoir": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
+ "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
+ "dev": true,
+ "dependencies": {
+ "resolve": "^1.20.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/registry-auth-token": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz",
+ "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==",
+ "dev": true,
+ "dependencies": {
+ "@pnpm/npm-conf": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/registry-url": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz",
+ "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==",
+ "dev": true,
+ "dependencies": {
+ "rc": "1.2.8"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/relateurl": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
+ "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/remote-git-tags": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/remote-git-tags/-/remote-git-tags-3.0.0.tgz",
+ "integrity": "sha512-C9hAO4eoEsX+OXA4rla66pXZQ+TLQ8T9dttgQj18yuKlPMTVkIkdYXvlMC55IuUsIkV6DpmQYi10JKFLaU+l7w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/renderkid": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz",
+ "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==",
+ "dev": true,
+ "dependencies": {
+ "css-select": "^4.1.3",
+ "dom-converter": "^0.2.0",
+ "htmlparser2": "^6.1.0",
+ "lodash": "^4.17.21",
+ "strip-ansi": "^6.0.1"
+ }
+ },
+ "node_modules/renderkid/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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/renderkid/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,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/requizzle": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz",
+ "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.17.21"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.6",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz",
+ "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-alpn": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
+ "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==",
+ "dev": true
+ },
+ "node_modules/resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "dependencies": {
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-protobuf-schema": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz",
+ "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==",
+ "dependencies": {
+ "protocol-buffers-schema": "^3.3.1"
+ }
+ },
+ "node_modules/responselike": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz",
+ "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==",
+ "dev": true,
+ "dependencies": {
+ "lowercase-keys": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/retry": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz",
+ "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^10.3.7"
+ },
+ "bin": {
+ "rimraf": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "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,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "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,
+ "optional": true
+ },
+ "node_modules/schema-utils": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz",
+ "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "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,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/semver-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz",
+ "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/semver-utils": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/semver-utils/-/semver-utils-1.1.4.tgz",
+ "integrity": "sha512-EjnoLE5OGmDAVV/8YDoN5KiajNadjzIp9BAHOhYeQHt7j0UWxjmgsx4YD48wp4Ue1Qogq38F1GNUJNqF1kKKxA==",
+ "dev": true
+ },
+ "node_modules/semver/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,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/serialize-javascript": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
+ "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==",
+ "dev": true,
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
+ "dev": true
+ },
+ "node_modules/shallow-clone": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
+ "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-command": {
+ "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,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/sigstore": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-1.9.0.tgz",
+ "integrity": "sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A==",
+ "dev": true,
+ "dependencies": {
+ "@sigstore/bundle": "^1.1.0",
+ "@sigstore/protobuf-specs": "^0.2.0",
+ "@sigstore/sign": "^1.0.0",
+ "@sigstore/tuf": "^1.0.3",
+ "make-fetch-happen": "^11.0.1"
+ },
+ "bin": {
+ "sigstore": "bin/sigstore.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/sisteransi": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+ "dev": true
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/smart-buffer": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
+ "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
+ "dev": true,
+ "dependencies": {
+ "ip": "^2.0.0",
+ "smart-buffer": "^4.2.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks-proxy-agent": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz",
+ "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "^6.0.2",
+ "debug": "^4.3.3",
+ "socks": "^2.6.2"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/spawn-please": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/spawn-please/-/spawn-please-2.0.2.tgz",
+ "integrity": "sha512-KM8coezO6ISQ89c1BzyWNtcn2V2kAVtwIXd3cN/V5a0xPYc1F/vydrRc01wsKFEQ/p+V1a4sw4z2yMITIXrgGw==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.3"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/spdx-correct": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
+ "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
+ "dev": true,
+ "dependencies": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+ "dev": true
+ },
+ "node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-license-ids": {
+ "version": "3.0.16",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz",
+ "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==",
+ "dev": true
+ },
+ "node_modules/ssri": {
+ "version": "10.0.5",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz",
+ "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/ssri/node_modules/minipass": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
+ "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "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,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width/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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width/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,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "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,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/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,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/style-loader": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.3.tgz",
+ "integrity": "sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.0.0"
+ }
+ },
+ "node_modules/stylehacks": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.0.0.tgz",
+ "integrity": "sha512-+UT589qhHPwz6mTlCLSt/vMNTJx8dopeJlZAlBMJPWA3ORqu6wmQY7FBXf+qD+FsqoBJODyqNxOUP3jdntFRdw==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.21.4",
+ "postcss-selector-parser": "^6.0.4"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "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,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/svgo": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.0.2.tgz",
+ "integrity": "sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==",
+ "dev": true,
+ "dependencies": {
+ "@trysound/sax": "0.2.0",
+ "commander": "^7.2.0",
+ "css-select": "^5.1.0",
+ "css-tree": "^2.2.1",
+ "csso": "^5.0.5",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "svgo": "bin/svgo"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/svgo"
+ }
+ },
+ "node_modules/svgo/node_modules/commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/svgo/node_modules/css-select": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
+ "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+ "dev": true,
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.1.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/svgo/node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dev": true,
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/svgo/node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/svgo/node_modules/domutils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
+ "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
+ "dev": true,
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/svgo/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,
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/tapable": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tar": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz",
+ "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==",
+ "dev": true,
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^5.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/tar/node_modules/fs-minipass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "dev": true,
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.21.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz",
+ "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.8.2",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser-webpack-plugin": {
+ "version": "5.3.9",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
+ "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jest-worker": "^27.4.5",
+ "schema-utils": "^3.1.1",
+ "serialize-javascript": "^6.0.1",
+ "terser": "^5.16.8"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "uglify-js": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/terser-webpack-plugin/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,
+ "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/terser-webpack-plugin/node_modules/ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "dev": true,
+ "peerDependencies": {
+ "ajv": "^6.9.1"
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/jest-worker": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
+ "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/terser-webpack-plugin/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/terser-webpack-plugin/node_modules/schema-utils": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/terser/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "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,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
+ "dev": true
+ },
+ "node_modules/tuf-js": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.7.tgz",
+ "integrity": "sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==",
+ "dev": true,
+ "dependencies": {
+ "@tufjs/models": "1.0.4",
+ "debug": "^4.3.4",
+ "make-fetch-happen": "^11.1.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
+ "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typedarray-to-buffer": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+ "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+ "dev": true,
+ "dependencies": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
+ "node_modules/uc.micro": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
+ "dev": true
+ },
+ "node_modules/underscore": {
+ "version": "1.13.6",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
+ "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==",
+ "dev": true
+ },
+ "node_modules/unique-filename": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz",
+ "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==",
+ "dev": true,
+ "dependencies": {
+ "unique-slug": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/unique-slug": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz",
+ "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==",
+ "dev": true,
+ "dependencies": {
+ "imurmurhash": "^0.1.4"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/unique-string": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz",
+ "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==",
+ "dev": true,
+ "dependencies": {
+ "crypto-random-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/untildify": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
+ "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+ "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/update-notifier": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz",
+ "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==",
+ "dev": true,
+ "dependencies": {
+ "boxen": "^7.0.0",
+ "chalk": "^5.0.1",
+ "configstore": "^6.0.0",
+ "has-yarn": "^3.0.0",
+ "import-lazy": "^4.0.0",
+ "is-ci": "^3.0.1",
+ "is-installed-globally": "^0.4.0",
+ "is-npm": "^6.0.0",
+ "is-yarn-global": "^0.4.0",
+ "latest-version": "^7.0.0",
+ "pupa": "^3.1.0",
+ "semver": "^7.3.7",
+ "semver-diff": "^4.0.0",
+ "xdg-basedir": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/yeoman/update-notifier?sponsor=1"
+ }
+ },
+ "node_modules/update-notifier/node_modules/chalk": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+ "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+ "dev": true,
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "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,
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "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/utila": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz",
+ "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==",
+ "dev": true
+ },
+ "node_modules/validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "dependencies": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "node_modules/validate-npm-package-name": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz",
+ "integrity": "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==",
+ "dev": true,
+ "dependencies": {
+ "builtins": "^5.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/watchpack": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
+ "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+ "dev": true,
+ "dependencies": {
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/web-worker": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz",
+ "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA=="
+ },
+ "node_modules/webpack": {
+ "version": "5.88.2",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz",
+ "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/eslint-scope": "^3.7.3",
+ "@types/estree": "^1.0.0",
+ "@webassemblyjs/ast": "^1.11.5",
+ "@webassemblyjs/wasm-edit": "^1.11.5",
+ "@webassemblyjs/wasm-parser": "^1.11.5",
+ "acorn": "^8.7.1",
+ "acorn-import-assertions": "^1.9.0",
+ "browserslist": "^4.14.5",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^5.15.0",
+ "es-module-lexer": "^1.2.1",
+ "eslint-scope": "5.1.1",
+ "events": "^3.2.0",
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.2.9",
+ "json-parse-even-better-errors": "^2.3.1",
+ "loader-runner": "^4.2.0",
+ "mime-types": "^2.1.27",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^3.2.0",
+ "tapable": "^2.1.1",
+ "terser-webpack-plugin": "^5.3.7",
+ "watchpack": "^2.4.0",
+ "webpack-sources": "^3.2.3"
+ },
+ "bin": {
+ "webpack": "bin/webpack.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependenciesMeta": {
+ "webpack-cli": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-cli": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz",
+ "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==",
+ "dev": true,
+ "dependencies": {
+ "@discoveryjs/json-ext": "^0.5.0",
+ "@webpack-cli/configtest": "^2.1.1",
+ "@webpack-cli/info": "^2.0.2",
+ "@webpack-cli/serve": "^2.0.5",
+ "colorette": "^2.0.14",
+ "commander": "^10.0.1",
+ "cross-spawn": "^7.0.3",
+ "envinfo": "^7.7.3",
+ "fastest-levenshtein": "^1.0.12",
+ "import-local": "^3.0.2",
+ "interpret": "^3.1.1",
+ "rechoir": "^0.8.0",
+ "webpack-merge": "^5.7.3"
+ },
+ "bin": {
+ "webpack-cli": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x"
+ },
+ "peerDependenciesMeta": {
+ "@webpack-cli/generators": {
+ "optional": true
+ },
+ "webpack-bundle-analyzer": {
+ "optional": true
+ },
+ "webpack-dev-server": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-cli/node_modules/commander": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/webpack-merge": {
+ "version": "5.9.0",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz",
+ "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==",
+ "dev": true,
+ "dependencies": {
+ "clone-deep": "^4.0.1",
+ "wildcard": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/webpack-sources": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
+ "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/webpack/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,
+ "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/webpack/node_modules/ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "dev": true,
+ "peerDependencies": {
+ "ajv": "^6.9.1"
+ }
+ },
+ "node_modules/webpack/node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
+ },
+ "node_modules/webpack/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/webpack/node_modules/schema-utils": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "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,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/wide-align": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
+ "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^1.0.2 || 2 || 3 || 4"
+ }
+ },
+ "node_modules/widest-line": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz",
+ "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/widest-line/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
+ },
+ "node_modules/widest-line/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,
+ "dependencies": {
+ "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/wildcard": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
+ "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
+ "dev": true
+ },
+ "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,
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "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,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/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
+ },
+ "node_modules/wrap-ansi/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,
+ "dependencies": {
+ "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/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-file-atomic": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
+ "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
+ "dev": true,
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "is-typedarray": "^1.0.0",
+ "signal-exit": "^3.0.2",
+ "typedarray-to-buffer": "^3.1.5"
+ }
+ },
+ "node_modules/write-file-atomic/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/xdg-basedir": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz",
+ "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/xml-utils": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/xml-utils/-/xml-utils-1.7.0.tgz",
+ "integrity": "sha512-bWB489+RQQclC7A9OW8e5BzbT8Tu//jtAOvkYwewFr+Q9T9KDGvfzC1lp0pYPEQPEoPQLDkmxkepSC/2gIAZGw=="
+ },
+ "node_modules/xmlcreate": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz",
+ "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==",
+ "dev": true
+ },
+ "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
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
--- /dev/null
+{
+ "name": "org.argeo.app.js",
+ "version": "2.3.0.next",
+ "description": "",
+ "private": "true",
+ "scripts": {
+ "build": "webpack --config webpack.dev.js",
+ "build-prod": "webpack --config webpack.prod.js"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "GPL",
+ "devDependencies": {
+ "css-loader": "^6.8.1",
+ "css-minimizer-webpack-plugin": "^5.0.1",
+ "html-webpack-plugin": "^5.5.3",
+ "jsdoc": "^4.0.2",
+ "mini-css-extract-plugin": "^2.7.6",
+ "npm-check-updates": "^16.13.2",
+ "style-loader": "^3.3.3",
+ "webpack": "^5.83.1",
+ "webpack-cli": "^5.1.1",
+ "webpack-merge": "^5.9.0"
+ },
+ "dependencies": {
+ "@nieuwlandgeo/sldreader": "0.3.x",
+ "chart.js": "4.x.x",
+ "chartjs-plugin-annotation": "^3.0.1",
+ "ol": "8.x.x"
+ }
+}
--- /dev/null
+import Chart from 'chart.js/auto';
+
+import ChartJsPart from './ChartJsPart.js';
+
+export default class BarChart extends ChartJsPart {
+ /** Constructor taking the mapName as an argument. */
+ constructor(chartName) {
+ super(chartName);
+ this.setChart(new Chart(this.getChartCanvas(), {
+ type: 'bar',
+ data: {
+ datasets: []
+ },
+ options: {
+ scales: {
+ y: {
+ beginAtZero: true
+ },
+ },
+ animation: false,
+ }
+ }));
+
+ }
+
+
+}
--- /dev/null
+import ChartPart from './ChartPart.js';
+
+import { Chart } from 'chart.js';
+import annotationPlugin from 'chartjs-plugin-annotation';
+
+Chart.register(annotationPlugin);
+
+export default class ChartJsPart extends ChartPart {
+ #chart;
+
+ /** Constructor taking the mapName as an argument. */
+ constructor(chartName) {
+ super(chartName);
+ }
+
+ setChart(chart) {
+ this.#chart = chart;
+ }
+
+ getChart() {
+ return this.#chart;
+ }
+
+ //
+ // DATA
+ //
+ setLabels(labels) {
+ const chart = this.getChart();
+ chart.data.labels = labels;
+ this.update();
+ }
+
+ addDataset(label, data) {
+ const chart = this.getChart();
+ chart.data.datasets.push({
+ label: label,
+ data: data,
+ borderWidth: 1
+ });
+ this.update();
+ }
+
+ setData(labels, label, data) {
+ this.clearDatasets();
+ this.setLabels(labels);
+ this.addDataset(label, data);
+ }
+
+ setDatasets(labels, datasets) {
+ const chart = this.getChart();
+ chart.data.datasets = datasets;
+ chart.data.labels = labels;
+ this.update();
+ }
+
+ clearDatasets() {
+ const chart = this.getChart();
+ chart.data.datasets = [];
+ this.update();
+ }
+
+ update() {
+ this.#chart.update();
+ }
+}
--- /dev/null
+/** API to be used by Java.
+ * @module MapPart
+ */
+
+/** Abstract base class for displaying a map. */
+export default class ChartPart {
+
+ /** The name of the chart, will also be the name of the variable */
+ #chartName;
+
+ constructor(chartName) {
+ this.#chartName = chartName;
+ this.createChartCanvas(this.#chartName);
+ }
+
+
+ //
+ // HTML
+ //
+ /** Create the div element where the chart will be displayed. */
+ createChartCanvas(id) {
+ const chartDiv = document.createElement('canvas');
+ chartDiv.id = id;
+ //chartDiv.style.cssText = 'width: 100%;';
+ chartDiv.style.cssText = 'width: 100%; height: 100vh;';
+ document.body.appendChild(chartDiv);
+ }
+
+ /** Get the div element where the chart is displayed. */
+ getChartCanvas() {
+ return document.getElementById(this.#chartName);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+import Chart from 'chart.js/auto';
+
+export default class TestGraph {
+
+ init() {
+ const ctx = document.getElementById('myChart');
+
+ new Chart(ctx, {
+ type: 'bar',
+ data: {
+ labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
+ datasets: [{
+ label: '# of Votes',
+ data: [12, 19, 3, 5, 2, 3],
+ borderWidth: 1
+ }]
+ },
+ options: {
+ scales: {
+ y: {
+ beginAtZero: true
+ }
+ }
+ }
+ });
+ }
+}
--- /dev/null
+import BarChart from './BarChart.js';
+import TestGraph from './TestGraph.js';
+//import { rectY, binX } from "@observablehq/plot";
+
+// PSEUDO PACKAGE
+if (typeof globalThis.argeo === 'undefined')
+ globalThis.argeo = {};
+if (typeof globalThis.argeo.app === 'undefined')
+ globalThis.argeo.app = {};
+if (typeof globalThis.argeo.app.chart === 'undefined')
+ globalThis.argeo.app.chart = {};
+
+// PUBLIC CLASSES
+globalThis.argeo.app.chart.BarChart = BarChart;
+globalThis.argeo.app.chart.TestGraph = TestGraph;
+
+//const plot = rectY({ length: 10000 }, binX({ y: "count" }, { x: Math.random })).plot();
+//const div = document.querySelector("#myplot");
+//div.append(plot);
+
+"use strict";
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta charset="UTF-8">
+</head>
+
+<body>
+</body>
+
+</html>
\ No newline at end of file
--- /dev/null
+import './export-package.js';
--- /dev/null
+
+import VectorSource from 'ol/source/Vector.js';
+import { bbox } from 'ol/loadingstrategy';
+import { transformToEpsg4326LatLonExtent } from './OpenLayersUtils.js';
+
+export default class BboxVectorSource extends VectorSource {
+ constructor(options) {
+ super(BboxVectorSource.processOptions(options));
+ }
+
+ static processOptions(options) {
+ options.strategy = bbox;
+ options.url = function(extent, resolution, projection) {
+ var bbox = transformToEpsg4326LatLonExtent(extent, projection);
+
+ const baseUrl = options.baseUrl;
+ // invert bbox order in order to have minLat,minLon,maxLat,maxLon as required by WFS 2.0.0
+ const url = baseUrl + '&bbox=' + bbox.join(',') + ',EPSG:4326';
+ return url;
+ }
+ return options;
+ }
+
+
+}
\ No newline at end of file
--- /dev/null
+/** API to be used by Java.
+ * @module MapPart
+ */
+
+/** Abstract base class for displaying a map. */
+export default class MapPart {
+
+ /** The name of the map, will also be the name of the variable */
+ #mapName;
+
+ constructor(mapName) {
+ this.#mapName = mapName;
+ this.createMapDiv(this.#mapName);
+ }
+
+ //
+ // ABSTRACT METHODS
+ //
+ /** Set the center of the map to the given coordinates. */
+ setCenter(lng, lat) {
+ throw new Error("Abstract method");
+ }
+
+ //
+ // EXTENSIONS
+ //
+ loadMapModule(url) {
+ var script = document.createElement("script");
+ script.src = url;
+ document.head.appendChild(script);
+ // import(url)
+ // .then(module => { })
+ // .catch((error) => 'An error occurred while loading the component');
+ }
+
+ //
+ // ACCESSORS
+ //
+ getMapName() {
+ return this.#mapName;
+ }
+
+ //
+ // HTML
+ //
+ createMapDiv(id) {
+ var mapDiv = document.createElement('div');
+ mapDiv.id = id;
+ mapDiv.className = this.getMapDivCssClass();
+ mapDiv.style.cssText = 'width: 100%; height: 100vh;';
+ document.body.appendChild(mapDiv);
+ }
+
+ getMapDivCssClass() {
+ throw new Error("Abstract method");
+ }
+
+ newObject(js) {
+ const func = new Function(js);
+ return (func());
+ }
+}
--- /dev/null
+/** OpenLayers-based implementation.
+ * @module OpenLayersMapPart
+ */
+
+import { fromLonLat, getPointResolution } from 'ol/proj.js';
+
+import TileLayer from 'ol/layer/Tile.js';
+
+import OSM from 'ol/source/OSM.js';
+import { isEmpty } from 'ol/extent';
+
+import Select from 'ol/interaction/Select.js';
+import Overlay from 'ol/Overlay.js';
+
+import Map from 'ol/Map.js';
+
+import { OverviewMap, ScaleLine, defaults as defaultControls } from 'ol/control.js';
+import { easeOut } from 'ol/easing';
+
+import * as SLDReader from '@nieuwlandgeo/sldreader';
+
+import MapPart from './MapPart.js';
+import { transformToOlLonLatExtent } from './OpenLayersUtils.js';
+
+/** OpenLayers implementation of MapPart. */
+export default class OpenLayersMapPart extends MapPart {
+ /** The OpenLayers Map. */
+ #map;
+
+ /** The overview map */
+ #overviewMap;
+
+ /** Styled layer descriptor */
+ #sld;
+
+ /** The select interaction */
+ select;
+
+ /** Externally added callback functions. */
+ callbacks = {};
+
+ /** Constructor taking the mapName as an argument. */
+ constructor(mapName) {
+ super(mapName);
+ this.#overviewMap = new OverviewMap({
+ layers: [
+ new TileLayer({
+ source: new OSM(),
+ }),
+ ],
+ });
+ this.select = new Select();
+ this.#map = new Map({
+ controls: defaultControls({
+ attribution: false,
+ rotate: false,
+ }).extend([this.#overviewMap, new ScaleLine({
+ bar: false,
+ steps: 2,
+ text: false,
+ minWidth: 150,
+ maxWidth: 200,
+ })]),
+ layers: [
+ ],
+ // view: new View({
+ // projection: 'EPSG:4326',
+ // center: [0, 0],
+ // zoom: 2,
+ // }),
+ target: this.getMapName(),
+ });
+ this.#map.addInteraction(this.select);
+ //this.#map.getView().set('projection', 'EPSG:4326', true);
+ }
+
+ /* GEOGRAPHICAL METHODS */
+
+ setCenter(lat, lon) {
+ this.#map.getView().setCenter(fromLonLat([lon, lat]));
+ }
+
+ fit(extent, options) {
+ var transformed = transformToOlLonLatExtent(extent, this.#map.getView().getProjection());
+ this.#map.getView().fit(transformed, options);
+ }
+
+ /** Accessors */
+ getMap() {
+ return this.#map;
+ }
+
+ getLayerByName(name) {
+ let layers = this.#map.getLayers();
+ for (let i = 0; i < layers.getLength(); i++) {
+ let layer = layers.item(i);
+ let n = layer.get('name');
+ if (n !== undefined) {
+ if (name === n)
+ return layer;
+ }
+ }
+ return undefined;
+ }
+
+ /* CALLBACKS */
+ enableFeatureSingleClick() {
+ // we cannot use 'this' in the function provided to OpenLayers
+ let mapPart = this;
+ this.#map.on('singleclick', function(e) {
+ let feature = null;
+ // we chose the first one
+ e.map.forEachFeatureAtPixel(e.pixel, function(f) {
+ feature = f;
+ return true;
+ });
+ if (feature !== null)
+ mapPart.callbacks['onFeatureSingleClick'](feature.get('cr:path'));
+ });
+ }
+
+ enableFeatureSelected() {
+ // we cannot use 'this' in the function provided to OpenLayers
+ let mapPart = this;
+ var select = new Select();
+ this.#map.addInteraction(select);
+ select.on('select', function(e) {
+ if (e.selected.length > 0) {
+ let feature = e.selected[0];
+ mapPart.callbacks['onFeatureSelected'](feature.get('cr:path'));
+ }
+ });
+ }
+
+ enableFeaturePopup() {
+ // we cannot use 'this' in the function provided to OpenLayers
+ let mapPart = this;
+ /**
+ * Elements that make up the popup.
+ */
+ const container = document.getElementById('popup');
+ const content = document.getElementById('popup-content');
+ const closer = document.getElementById('popup-closer');
+
+ /**
+ * Create an overlay to anchor the popup to the map.
+ */
+ const overlay = new Overlay({
+ element: container,
+ autoPan: false,
+ autoPanAnimation: {
+ duration: 250,
+ },
+ });
+ this.#map.addOverlay(overlay);
+
+ let selected = null;
+ this.#map.on('pointermove', function(e) {
+ if (selected !== null) {
+ selected.setStyle(undefined);
+ selected = null;
+ }
+
+ e.map.forEachFeatureAtPixel(e.pixel, function(f) {
+ selected = f;
+ return true;
+ });
+
+ if (selected == null) {
+ overlay.setPosition(undefined);
+ return;
+ }
+ const coordinate = e.coordinate;
+ const path = selected.get('cr:path');
+ if (path === null)
+ return true;
+ const res = mapPart.callbacks['onFeaturePopup'](path);
+ if (res != null) {
+ content.innerHTML = res;
+ overlay.setPosition(coordinate);
+ } else {
+ overlay.setPosition(undefined);
+ }
+ });
+ }
+
+ selectFeatures(layerName, featureIds) {
+ // we cannot use 'this' in the function provided to OpenLayers
+ let mapPart = this;
+ this.select.getFeatures().clear();
+ const layer = this.getLayerByName(layerName);
+ const source = layer.getSource();
+ for (const featureId of featureIds) {
+ let feature = source.getFeatureById(featureId);
+ if (feature === null) {
+ source.on('featuresloadend', function(e) {
+ feature = source.getFeatureById(featureId);
+ if (feature !== null)
+ mapPart.select.getFeatures().push(feature);
+ });
+ } else {
+ this.select.getFeatures().push(feature);
+ }
+ }
+ }
+
+ fitToLayer(layerName) {
+ // we cannot use 'this' in the function provided to OpenLayers
+ let mapPart = this;
+ const layer = this.getLayerByName(layerName);
+ const source = layer.getSource();
+ const extent = source.getExtent();
+ const options = {
+ duration: 1000,
+ padding: [20, 20, 20, 20],
+ easing: easeOut,
+ };
+ if (!isEmpty(extent))
+ this.#map.getView().fit(source.getExtent(), options);
+ source.on('featuresloadend', function(e) {
+ mapPart.getMap().getView().fit(source.getExtent(), options);
+ });
+ }
+
+ //
+ // HTML
+ //
+ getMapDivCssClass() {
+ return 'map';
+ }
+
+
+ //
+ // STATIC FOR EXTENSION
+ //
+ static newStyle(args) {
+ return new Style(args);
+ }
+
+ static newIcon(args) {
+ return new Icon(args);
+ }
+
+ //
+ // SLD STYLING
+ //
+
+ setSld(xml) {
+ this.#sld = SLDReader.Reader(xml);
+ }
+
+ /** Get a FeatureTypeStyle (https://nieuwlandgeo.github.io/SLDReader/api.html#FeatureTypeStyle). */
+ getFeatureTypeStyle(styledLayerName, styleName) {
+ const sldLayer = SLDReader.getLayer(this.#sld, styledLayerName);
+ const style = styleName === undefined ? SLDReader.getStyle(sldLayer) : SLDReader.getStyle(sldLayer, styleName);
+ // OpenLayers can only use one definition
+ const featureTypeStyle = style.featuretypestyles[0];
+ return featureTypeStyle;
+ }
+
+ applyStyle(layerName, styledLayerName, styleName) {
+ const layer = this.getLayerByName(layerName);
+ const featureTypeStyle = this.getFeatureTypeStyle(styledLayerName, styleName);
+ const viewProjection = this.#map.getView().getProjection();
+ const olStyleFunction = SLDReader.createOlStyleFunction(featureTypeStyle, {
+ // Use the convertResolution option to calculate a more accurate resolution.
+ convertResolution: viewResolution => {
+ const viewCenter = this.#map.getView().getCenter();
+ return getPointResolution(viewProjection, viewResolution, viewCenter);
+ },
+ // If you use point icons with an ExternalGraphic, you have to use imageLoadCallback
+ // to update the vector layer when an image finishes loading.
+ // If you do not do this, the image will only be visible after next layer pan/zoom.
+ imageLoadedCallback: () => {
+ layer.changed();
+ },
+ });
+ layer.setStyle(olStyleFunction);
+ }
+
+ #applySLD(vectorLayer, text) {
+ const sldObject = SLDReader.Reader(text);
+ const sldLayer = SLDReader.getLayer(sldObject);
+ const style = SLDReader.getStyle(sldLayer);
+ const featureTypeStyle = style.featuretypestyles[0];
+
+ const viewProjection = this.#map.getView().getProjection();
+ const olStyleFunction = SLDReader.createOlStyleFunction(featureTypeStyle, {
+ // Use the convertResolution option to calculate a more accurate resolution.
+ convertResolution: viewResolution => {
+ const viewCenter = this.#map.getView().getCenter();
+ return getPointResolution(viewProjection, viewResolution, viewCenter);
+ },
+ // If you use point icons with an ExternalGraphic, you have to use imageLoadCallback
+ // to update the vector layer when an image finishes loading.
+ // If you do not do this, the image will only be visible after next layer pan/zoom.
+ imageLoadedCallback: () => {
+ vectorLayer.changed();
+ },
+ });
+ vectorLayer.setStyle(olStyleFunction);
+ }
+}
--- /dev/null
+import { transformExtent } from 'ol/proj.js';
+
+
+export function transformToEpsg4326LatLonExtent(extent, projection) {
+ const proj = projection.getCode();
+ if (proj === 'EPSG:4326')
+ return toLatLonExtent(extent);
+ var transformed = transformExtent(extent, proj, 'EPSG:4326');
+ return toLatLonExtent(transformed);
+}
+
+/** From EPSG:4326 lat/lon to a proj lon/lat */
+export function transformToOlLonLatExtent(extent, projection) {
+ const proj = projection.getCode();
+ if (proj === 'EPSG:4326')
+ return toLonLatExtent(extent);
+ const reordered = toLonLatExtent(extent);
+ var transformed = transformExtent(reordered, 'EPSG:4326', proj);
+ return transformed;
+}
+
+/** Converts from an extent in OpenLayers order (lon/lat) to WFS 2.0 order (lat/lon). */
+export function toLatLonExtent(extent) {
+ return [extent[1], extent[0], extent[3], extent[2]];
+}
+
+/** Converts from an extent in WFS 2.0 order (lat/lon) to OpenLayers order (lon/lat) . */
+export function toLonLatExtent(extent) {
+ return [extent[1], extent[0], extent[3], extent[2]];
+}
+
--- /dev/null
+
+import WMTS from 'ol/source/WMTS.js';
+import WMTSTileGrid from 'ol/tilegrid/WMTS';
+import { getTopLeft } from 'ol/extent';
+import { getWidth } from 'ol/extent';
+import { get as getProjection } from 'ol/proj';
+
+export default class SentinelCloudless extends WMTS {
+ static source_s2CL2019;
+ static EPSG4326 = getProjection('EPSG:4326');
+
+ static resolutions;
+ static matrixIds;
+
+ static {
+ let min_zoom = 6;
+ let max_zoom = 17;
+ let zoomOffset = 1;
+
+ // from https://s2maps.eu/
+ let size = getWidth(this.EPSG4326.getExtent()) / 512;
+ this.resolutions = new Array(max_zoom + zoomOffset);
+ this.matrixIds = new Array(max_zoom + zoomOffset);
+ for (let z = min_zoom; z <= max_zoom; ++z) {
+ // generate resolutions and matrixIds arrays for this WMTS
+ this.resolutions[z] = size / Math.pow(2, z);
+ this.matrixIds[z] = z;
+ }
+ }
+
+ constructor() {
+ super({
+ urls: [
+ "//a.s2maps-tiles.eu/wmts/",
+ "//b.s2maps-tiles.eu/wmts/",
+ "//c.s2maps-tiles.eu/wmts/",
+ "//d.s2maps-tiles.eu/wmts/",
+ "//e.s2maps-tiles.eu/wmts/"
+ ],
+ layer: 's2cloudless-2021',
+ matrixSet: 'WGS84',
+ format: 'image/jpeg',
+ projection: SentinelCloudless.EPSG4326,
+ tileGrid: new WMTSTileGrid({
+ origin: getTopLeft(SentinelCloudless.EPSG4326.getExtent()),
+ resolutions: SentinelCloudless.resolutions,
+ matrixIds: SentinelCloudless.matrixIds,
+ }),
+ style: 'default',
+ transition: 0,
+ wrapX: true
+ });
+ }
+}
\ No newline at end of file
--- /dev/null
+import OpenLayersMapPart from './OpenLayersMapPart.js';
+import BboxVectorSource from './BboxVectorSource.js';
+import SentinelCloudless from './SentinelCloudless.js';
+
+import Map from 'ol/Map.js';
+import View from 'ol/View.js';
+import OSM from 'ol/source/OSM.js';
+import TileLayer from 'ol/layer/Tile.js';
+import VectorSource from 'ol/source/Vector.js';
+import VectorLayer from 'ol/layer/Vector.js';
+import GeoJSON from 'ol/format/GeoJSON.js';
+import { Style, Icon } from 'ol/style.js';
+
+// PSEUDO PACKAGE
+if (typeof globalThis.argeo === 'undefined')
+ globalThis.argeo = {};
+if (typeof globalThis.argeo.app === 'undefined')
+ globalThis.argeo.app = {};
+if (typeof globalThis.argeo.app.geo === 'undefined')
+ globalThis.argeo.app.geo = {};
+
+// THIRD PARTY
+if (typeof globalThis.argeo.tp === 'undefined')
+ globalThis.argeo.tp = {};
+if (typeof globalThis.argeo.tp.ol === 'undefined')
+ globalThis.argeo.tp.ol = {};
+
+// PUBLIC CLASSES
+globalThis.argeo.app.geo.OpenLayersMapPart = OpenLayersMapPart;
+globalThis.argeo.app.geo.BboxVectorSource = BboxVectorSource;
+globalThis.argeo.app.geo.SentinelCloudless = SentinelCloudless;
+
+globalThis.argeo.tp.ol.Map = Map;
+globalThis.argeo.tp.ol.View = View;
+globalThis.argeo.tp.ol.TileLayer = TileLayer;
+globalThis.argeo.tp.ol.OSM = OSM;
+globalThis.argeo.tp.ol.VectorSource = VectorSource;
+globalThis.argeo.tp.ol.VectorLayer = VectorLayer;
+globalThis.argeo.tp.ol.GeoJSON = GeoJSON;
+globalThis.argeo.tp.ol.Style = Style;
+globalThis.argeo.tp.ol.Icon = Icon;
+
+"use strict";
+
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta charset="UTF-8">
+ <style>
+ .ol-popup {
+ position: absolute;
+ background-color: white;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
+ padding: 5px;
+ border-radius: 10px;
+ border: 1px solid #cccccc;
+ bottom: 12px;
+ left: -50px;
+ min-width: 130px;
+ }
+
+ .ol-popup:after,
+ .ol-popup:before {
+ top: 100%;
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+ pointer-events: none;
+ }
+
+ .ol-popup:after {
+ border-top-color: white;
+ border-width: 10px;
+ left: 48px;
+ margin-left: -10px;
+ }
+
+ .ol-popup:before {
+ border-top-color: #cccccc;
+ border-width: 11px;
+ left: 48px;
+ margin-left: -11px;
+ }
+
+ .ol-popup-closer {
+ text-decoration: none;
+ position: absolute;
+ top: 2px;
+ right: 8px;
+ }
+
+ .ol-popup-closer:after {
+ content: "✖";
+ }
+
+ .map .ol-scale-line {
+ bottom: 0px;
+ left: 50%;
+ margin-right: -50%;
+ transform: translate(-50%, -50%);
+ }
+
+ .map .ol-scale-bar {
+ bottom: 0px;
+ left: 50%;
+ margin-right: -50%;
+ transform: translate(-50%, -50%);
+ }
+
+ #popup-content {
+ font: 16px sans-serif;
+ }
+ </style>
+</head>
+
+<body>
+ <!-- Popup -->
+ <div id="popup" class="ol-popup">
+ <div id="popup-content"></div>
+ </div>
+</body>
+
+</html>
\ No newline at end of file
--- /dev/null
+import './export-package.js';
+
+// webpack specific
+import 'ol/ol.css';
--- /dev/null
+const MiniCssExtractPlugin = require('mini-css-extract-plugin');
+//const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const path = require('path');
+
+module.exports = {
+ entry: {
+ "geo": './src/geo/index.js',
+ "chart": './src/chart/index.js',
+ },
+ output: {
+ filename: '[name].[contenthash].js',
+ path: path.resolve(__dirname, 'org.argeo.app.js/org/argeo/app/js'),
+ publicPath: '/pkg/org.argeo.app.js',
+ clean: true,
+ },
+ optimization: {
+ moduleIds: 'deterministic',
+ runtimeChunk: 'single',
+ // split code
+ splitChunks: {
+ chunks: 'all',
+ },
+ // minimizer: [
+ // // For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
+ // `...`,
+ // new CssMinimizerPlugin(),
+ // ],
+ },
+ module: {
+ rules: [
+ {
+ test: /\.(css)$/,
+ use: [
+ MiniCssExtractPlugin.loader,
+ 'css-loader',
+ ],
+ },
+ ],
+ },
+ plugins: [
+ // deal with CSS
+ new MiniCssExtractPlugin(),
+ // deal with HTML generation
+ new HtmlWebpackPlugin({
+ title: 'Argeo Suite Geo JS',
+ template: 'src/geo/index.html',
+ scriptLoading: 'module',
+ filename: 'geo.html',
+ chunks: ['geo'],
+ }),
+ new HtmlWebpackPlugin({
+ title: 'Argeo Suite Chart JS',
+ template: 'src/chart/index.html',
+ scriptLoading: 'module',
+ filename: 'chart.html',
+ chunks: ['chart'],
+ }),
+
+ ],
+};
\ No newline at end of file
--- /dev/null
+const { merge } = require('webpack-merge');
+const common = require('./webpack.common.js');
+
+module.exports = merge(common, {
+ mode: 'development',
+ //devtool: 'source-map', // original code
+ devtool: 'eval-source-map',
+ devServer: {
+ static: './dist',
+ },
+});
\ No newline at end of file
--- /dev/null
+const { merge } = require('webpack-merge');
+const common = require('./webpack.common.js');
+
+module.exports = merge(common, {
+ mode: 'production',
+ devtool: 'source-map', // original code
+});
\ No newline at end of file
/** Constant related to entities, typically used in an OSGi context. */
public interface EntityConstants {
final static String TYPE = "entity.type";
- final static String DEFAULT_EDITOR_ID = "entity.defaultEditorId";
+// final static String DEFAULT_EDITOR_ID = "entity.defaultEditorId";
}
package org.argeo.app.api;
-import javax.jcr.Node;
-
/** The definition of an entity, a composite configurable data structure. */
public interface EntityDefinition {
- String getEditorId(Node entity);
+// String getEditorId(Node entity);
String getType();
}
import org.argeo.api.acr.QNamed;
+/** Names used in the entity namespace http://www.argeo.org/ns/entity. */
public enum EntityName implements QNamed {
- type, //
+ type, relatedTo, //
+ // time,
+ date,
+ // geography
+ minLat, minLon, maxLat, maxLon,
+ // geo entities
+ place,
+ //
;
@Override
final String ADM = "adm";
@Deprecated
- final String ENTITY_TYPE = "entity:type";
+ final String ENTITY_TYPE = EntityName.type.get();
// GENERIC CONCEPTS
// /** The language which is relevant. */
// final String XML_LANG = "xml:lang";
/** The date which is relevant. */
@Deprecated
- final String ENTITY_DATE = "entity:date";
+ final String ENTITY_DATE = EntityName.date.get();
@Deprecated
- final String ENTITY_RELATED_TO = "entity:relatedTo";
+ final String ENTITY_RELATED_TO = EntityName.relatedTo.get();
// DEFAULT FOLDER NAMES
final String MEDIA = "media";
// LDAP-LIKE ENTITIES
@Deprecated
- final String DISPLAY_NAME = LdapAttr.displayName.property();
+ final String DISPLAY_NAME = LdapAttr.displayName.get();
// Persons
@Deprecated
- final String GIVEN_NAME = LdapAttr.givenName.property();
+ final String GIVEN_NAME = LdapAttr.givenName.get();
@Deprecated
- final String SURNAME = LdapAttr.sn.property();
+ final String SURNAME = LdapAttr.sn.get();
@Deprecated
- final String EMAIL = LdapAttr.mail.property();
+ final String EMAIL = LdapAttr.mail.get();
@Deprecated
- final String OU = LdapAttr.ou.property();
+ final String OU = LdapAttr.ou.get();
// WGS84
@Deprecated
final String GEO_LAT = WGS84PosName.lat.get();
@Deprecated
- final String GEO_LONG = WGS84PosName.lng.get();
+ final String GEO_LONG = WGS84PosName.lon.get();
@Deprecated
final String GEO_ALT = WGS84PosName.alt.get();
import org.argeo.api.acr.QNamed;
-/** Types related to entities. */
+/** Types used in the entity namespace http://www.argeo.org/ns/entity. */
public enum EntityType implements QNamed {
// entity
entity, local, relatedTo,
// graphics
box,
// geography
- geopoint, bearing,
+ geopoint, bearing, geobounded,
// ldap
person, user;
* @see https://www.w3.org/2003/01/geo/
*/
public enum WGS84PosName implements QNamed {
- lat, lng("long"), alt;
+ lat, lon("long"), alt;
private final String localName;
[entity:bearing]
mixin
- svg:direction (DOUBLE)
+
+[entity:geobounded]
+mixin
+- entity:minLat (DOUBLE)
+- entity:minLon (DOUBLE)
+- entity:maxLat (DOUBLE)
+- entity:maxLon (DOUBLE)
+- entity:minAlt (DOUBLE)
+- entity:maxAlt (DOUBLE)
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified" attributeFormDefault="unqualified"
+ targetNamespace="http://www.argeo.org/ns/entity"
+ xmlns:entity="http://www.argeo.org/ns/entity">
+
+ <xs:attribute name="date" type="xs:date" />
+
+ <xs:element name="local">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##local" processContents="lax" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##any"
+ processContents="lax" />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="terms">
+ <xs:complexType>
+ <xs:sequence minOccurs="0" maxOccurs="unbounded">
+ <xs:element ref="entity:term"></xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="term">
+ <xs:complexType>
+ <xs:sequence minOccurs="0" maxOccurs="unbounded">
+ <xs:element ref="entity:term"></xs:element>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##any"
+ processContents="lax" />
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns="http://apaf.on.netiket.eu/ns/apaf"
+ targetNamespace="http://apaf.on.netiket.eu/ns/apaf"
+ xmlns:entity="http://www.argeo.org/ns/entity" xmlns:dav="DAV:"
+ xmlns:gml="http://www.opengis.net/gml">
+<!-- <xs:import -->
+<!-- schemaLocation="entity.xsd" -->
+<!-- namespace="http://www.argeo.org/ns/entity"></xs:import> -->
+ <!-- <xs:import -->
+ <!-- schemaLocation="https://schemas.opengis.net/gml/3.2.1/gml.xsd" -->
+ <!-- namespace="http://www.opengis.net/gml/3.2"></xs:import> -->
+ <xs:import namespace="http://www.opengis.net/gml"
+ schemaLocation="http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" />
+
+ <xs:complexType name="entityFeatureType">
+ <xs:complexContent>
+ <xs:extension base="gml:AbstractFeatureType">
+ <xs:sequence>
+ <xs:element name="area" type="gml:PolygonPropertyType" />
+ <xs:element name="geopoint" type="gml:PointPropertyType" />
+ <xs:element name="path" type="xs:string" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="entityFeature" type="entityFeatureType"
+ substitutionGroup="gml:_Feature" />
+
+ <!-- <xs:complexType name="TestFeatureCollectionType"> <xs:complexContent>
+ <xs:extension base="gml:AbstractFeatureCollectionType" /> </xs:complexContent>
+ </xs:complexType> <xs:element name="TestFeatureCollection" type="TestFeatureCollectionType"
+ /> -->
+
+</xs:schema>
\ No newline at end of file
OSGI-INF/termsContentProvider.xml,\
Import-Package:\
-tech.units.indriya.unit,\
+javax.measure.quantity,\
org.osgi.service.useradmin,\
-com.fasterxml.jackson.core,\
+tech.units.indriya.unit,\
org.argeo.cms.acr,\
*
--- /dev/null
+package org.argeo.app.core;
+
+import org.argeo.app.api.EntityDefinition;
+
+public abstract class AbstractEntityDefinition implements EntityDefinition {
+
+ public void init() {
+
+ }
+
+ public void destroy() {
+
+ }
+}
//
// ARGEO
//
- ENTITY("entity", "http://www.argeo.org/ns/entity", "entity.xsd", null),
+ ENTITY("entity", "http://www.argeo.org/ns/entity", "/org/argeo/app/api/entity.xsd", null),
//
ARGEO_DBK("argeodbk", "http://www.argeo.org/ns/argeodbk", null, null),
//
Objects.requireNonNull(namespace);
this.namespace = namespace;
if (resourceFileName != null) {
- resource = getClass().getResource(RESOURCE_BASE + resourceFileName);
+ if (!resourceFileName.startsWith("/"))
+ resource = getClass().getResource(RESOURCE_BASE + resourceFileName);
+ else
+ resource = getClass().getResource(resourceFileName);
Objects.requireNonNull(resource);
}
if (publicUrl != null)
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
- elementFormDefault="qualified" attributeFormDefault="unqualified"
- targetNamespace="http://www.argeo.org/ns/entity"
- xmlns:entity="http://www.argeo.org/ns/entity">
-
- <xs:attribute name="date" type="xs:date" />
-
- <xs:element name="local">
- <xs:complexType>
- <xs:sequence>
- <xs:any minOccurs="0" maxOccurs="unbounded"
- namespace="##local" processContents="lax" />
- </xs:sequence>
- <xs:anyAttribute namespace="##any"
- processContents="lax" />
- </xs:complexType>
- </xs:element>
-
- <xs:element name="terms">
- <xs:complexType>
- <xs:sequence minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="entity:term"></xs:element>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
-
- <xs:element name="term">
- <xs:complexType>
- <xs:sequence minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="entity:term"></xs:element>
- </xs:sequence>
- <xs:anyAttribute namespace="##any"
- processContents="lax" />
- </xs:complexType>
- </xs:element>
-</xs:schema>
\ No newline at end of file
+++ /dev/null
-package org.argeo.app.geo;
-
-import java.util.Map;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-/** Geo data utilities. */
-public class GeoJsonUtils {
-
- /** Add these properties to all features. */
- public static void addProperties(JsonNode tree, Map<String, String> map) {
- for (JsonNode feature : tree.get("features")) {
- ObjectNode properties = (ObjectNode) feature.get("properties");
- for (String key : map.keySet()) {
- properties.put(key, map.get(key));
- }
- }
- }
-
- /** Singleton. */
- private GeoJsonUtils() {
- }
-}
+++ /dev/null
-package org.argeo.app.geo;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Writer;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-/** Converts a geographical feature to an SVG. */
-public class GeoToSvg {
- public void convertGeoJsonToSvg(Path source, Path target) {
- ObjectMapper objectMapper = new ObjectMapper();
- try (InputStream in = Files.newInputStream(source);
- Writer out = Files.newBufferedWriter(target, StandardCharsets.UTF_8)) {
- JsonNode tree = objectMapper.readTree(in);
- JsonNode coord = tree.get("features").get(0).get("geometry").get("coordinates");
- double ratio = 100;
- double minX = Double.POSITIVE_INFINITY;
- double maxX = Double.NEGATIVE_INFINITY;
- double minY = Double.POSITIVE_INFINITY;
- double maxY = Double.NEGATIVE_INFINITY;
- List<String> shapes = new ArrayList<>();
- for (JsonNode shape : coord) {
- StringBuffer sb = new StringBuffer();
- sb.append("<polyline style=\"stroke-width:0.00000003;stroke:#000000;\" points=\"");
- for (JsonNode latlng : shape) {
- double lat = latlng.get(0).asDouble();
- double y = lat * ratio;
- if (y < minY)
- minY = y;
- if (y > maxY)
- maxY = y;
- double lng = latlng.get(1).asDouble();
- double x = lng * ratio;
- if (x < minX)
- minX = x;
- if (x > maxX)
- maxX = x;
- sb.append(y + "," + x + " ");
- }
- sb.append("\">");
- sb.append("</polyline>\n");
- shapes.add(sb.toString());
- }
-
- double width = maxX - minX;
- double height = maxY - minY;
- out.write("<svg xmlns=\"http://www.w3.org/2000/svg\"\n");
- out.write(" width=\"" + (int) (width * 1000) + "\"\n");
- out.write(" height=\"" + (int) (height * 1000) + "\"\n");
- out.write(" viewBox=\"" + minX + "," + minY + "," + width + "," + height + "\"\n");
- out.write(">\n");
- for (String shape : shapes) {
- out.write(shape);
- out.write("\n");
- }
- out.write("</svg>");
- } catch (IOException e) {
- throw new RuntimeException("Cannot convert " + source + " to " + target, e);
- }
- }
-
-}
+++ /dev/null
-package org.argeo.app.geo;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.InputStreamReader;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.geotools.data.DataUtilities;
-import org.geotools.data.DefaultTransaction;
-import org.geotools.data.Transaction;
-import org.geotools.data.collection.ListFeatureCollection;
-import org.geotools.data.shapefile.ShapefileDataStore;
-import org.geotools.data.shapefile.ShapefileDataStoreFactory;
-import org.geotools.data.simple.SimpleFeatureCollection;
-import org.geotools.data.simple.SimpleFeatureSource;
-import org.geotools.data.simple.SimpleFeatureStore;
-import org.geotools.feature.simple.SimpleFeatureBuilder;
-import org.geotools.geometry.jts.JTSFactoryFinder;
-import org.geotools.swing.data.JFileDataStoreChooser;
-import org.locationtech.jts.geom.Coordinate;
-import org.locationtech.jts.geom.Geometry;
-import org.locationtech.jts.geom.GeometryFactory;
-import org.locationtech.jts.geom.LineString;
-import org.locationtech.jts.geom.Point;
-import org.opengis.feature.simple.SimpleFeature;
-import org.opengis.feature.simple.SimpleFeatureType;
-
-public class GeoToolsTest {
- public GeoToolsTest() {
-
- }
-
- public void init() {
- try {
- main(null);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public void destroy() {
-
- }
-
- public static void main(String[] args) throws Exception {
- final SimpleFeatureType TYPE = DataUtilities.createType("Location", "the_geom:Point:srid=4326," + // <- the
- // geometry
- // attribute:
- // Point
- // type
- "name:String," + // <- a String attribute
- "number:Integer" // a number attribute
- );
- final SimpleFeatureType TYPE_HULL = DataUtilities.createType("Hull", "the_geom:MultiPolygon:srid=4326");
- System.out.println("TYPE:" + TYPE);
-
- /*
- * A list to collect features as we create them.
- */
- List<SimpleFeature> features = new ArrayList<>();
- List<Coordinate> coordinates = new ArrayList<>();
-
- /*
- * GeometryFactory will be used to create the geometry attribute of each
- * feature, using a Point object for the location.
- */
- GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
-
- SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
-
- try (BufferedReader reader = new BufferedReader(
- new InputStreamReader(GeoToolsTest.class.getResourceAsStream("/org/djapps/on/apaf/locations.csv")))) {
- /* First line of the data file is the header */
- String line = reader.readLine();
- System.out.println("Header: " + line);
-
- for (line = reader.readLine(); line != null; line = reader.readLine()) {
- if (line.trim().length() > 0) { // skip blank lines
- String[] tokens = line.split("\\,");
-
- double latitude = Double.parseDouble(tokens[0]);
- double longitude = Double.parseDouble(tokens[1]);
- String name = tokens[2].trim();
- int number = Integer.parseInt(tokens[3].trim());
-
- /* Longitude (= x coord) first ! */
- Coordinate coordinate = new Coordinate(longitude, latitude);
- coordinates.add(coordinate);
- Point point = geometryFactory.createPoint(coordinate);
-
- featureBuilder.add(point);
- featureBuilder.add(name);
- featureBuilder.add(number);
- SimpleFeature feature = featureBuilder.buildFeature(null);
- features.add(feature);
- }
- }
- }
-
- LineString lineString = geometryFactory
- .createLineString(coordinates.toArray(new Coordinate[coordinates.size()]));
- Geometry convexHull = lineString.convexHull();
- System.out.println(convexHull.toText());
- SimpleFeatureBuilder hullFeatureBuilder = new SimpleFeatureBuilder(TYPE_HULL);
- hullFeatureBuilder.add(convexHull);
- SimpleFeature hull = hullFeatureBuilder.buildFeature(null);
-
- /*
- * Get an output file name and create the new shapefile
- */
- File newFile = getNewShapeFile();
-
- ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
-
- Map<String, Serializable> params = new HashMap<>();
- params.put("url", newFile.toURI().toURL());
- params.put("create spatial index", Boolean.TRUE);
-
- ShapefileDataStore newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
-
- /*
- * TYPE is used as a template to describe the file contents
- */
- newDataStore.createSchema(TYPE_HULL);
-
- /*
- * Write the features to the shapefile
- */
- Transaction transaction = new DefaultTransaction("create");
-
- String typeName = newDataStore.getTypeNames()[0];
- SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName);
- SimpleFeatureType SHAPE_TYPE = featureSource.getSchema();
- /*
- * The Shapefile format has a couple limitations: - "the_geom" is always first,
- * and used for the geometry attribute name - "the_geom" must be of type Point,
- * MultiPoint, MuiltiLineString, MultiPolygon - Attribute names are limited in
- * length - Not all data types are supported (example Timestamp represented as
- * Date)
- *
- * Each data store has different limitations so check the resulting
- * SimpleFeatureType.
- */
- System.out.println("SHAPE:" + SHAPE_TYPE);
-
- if (featureSource instanceof SimpleFeatureStore) {
- SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
- /*
- * SimpleFeatureStore has a method to add features from a
- * SimpleFeatureCollection object, so we use the ListFeatureCollection class to
- * wrap our list of features.
- */
- SimpleFeatureCollection collection = new ListFeatureCollection(TYPE, Collections.singletonList(hull));
- featureStore.setTransaction(transaction);
- try {
- featureStore.addFeatures(collection);
- transaction.commit();
- } catch (Exception problem) {
- problem.printStackTrace();
- transaction.rollback();
- } finally {
- transaction.close();
- }
- } else {
- System.out.println(typeName + " does not support read/write access");
- }
-// if (featureSource instanceof SimpleFeatureStore) {
-// SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
-// /*
-// * SimpleFeatureStore has a method to add features from a
-// * SimpleFeatureCollection object, so we use the ListFeatureCollection class to
-// * wrap our list of features.
-// */
-// SimpleFeatureCollection collection = new ListFeatureCollection(TYPE, features);
-// featureStore.setTransaction(transaction);
-// try {
-// featureStore.addFeatures(collection);
-// transaction.commit();
-// } catch (Exception problem) {
-// problem.printStackTrace();
-// transaction.rollback();
-// } finally {
-// transaction.close();
-// }
-// } else {
-// System.out.println(typeName + " does not support read/write access");
-// }
- }
-
- /**
- * Prompt the user for the name and path to use for the output shapefile
- *
- * @param csvFile the input csv file used to create a default shapefile name
- * @return name and path for the shapefile as a new File object
- */
- private static File getNewShapeFile() {
-// String path = csvFile.getAbsolutePath();
-// String newPath = path.substring(0, path.length() - 4) + ".shp";
-
- JFileDataStoreChooser chooser = new JFileDataStoreChooser("shp");
- chooser.setDialogTitle("Save shapefile");
-// chooser.setSelectedFile(new File(newPath));
-
- int returnVal = chooser.showSaveDialog(null);
-
- if (returnVal != JFileDataStoreChooser.APPROVE_OPTION) {
- // the user cancelled the dialog
- System.exit(0);
- }
-
- File newFile = chooser.getSelectedFile();
-
- return newFile;
- }
-
-}
+++ /dev/null
-package org.argeo.app.geo;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.Writer;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.measure.Quantity;
-import javax.measure.quantity.Area;
-
-import org.geotools.data.DefaultTransaction;
-import org.geotools.data.Transaction;
-import org.geotools.data.collection.ListFeatureCollection;
-import org.geotools.data.shapefile.ShapefileDataStore;
-import org.geotools.data.shapefile.ShapefileDataStoreFactory;
-import org.geotools.data.simple.SimpleFeatureCollection;
-import org.geotools.data.simple.SimpleFeatureIterator;
-import org.geotools.data.simple.SimpleFeatureSource;
-import org.geotools.data.simple.SimpleFeatureStore;
-import org.geotools.geometry.jts.JTS;
-import org.geotools.referencing.CRS;
-import org.geotools.referencing.crs.DefaultGeographicCRS;
-import org.locationtech.jts.geom.Coordinate;
-import org.locationtech.jts.geom.Point;
-import org.locationtech.jts.geom.Polygon;
-import org.opengis.feature.simple.SimpleFeature;
-import org.opengis.feature.simple.SimpleFeatureType;
-import org.opengis.geometry.MismatchedDimensionException;
-import org.opengis.referencing.FactoryException;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.TransformException;
-
-import si.uom.SI;
-import tech.units.indriya.quantity.Quantities;
-
-/** Utilities around geographical format, mostly wrapping GeoTools patterns. */
-public class GeoUtils {
-
- /** In square meters. */
- public static Quantity<Area> calcArea(SimpleFeature feature) {
- try {
- Polygon p = (Polygon) feature.getDefaultGeometry();
- Point centroid = p.getCentroid();
- String code = "AUTO:42001," + centroid.getX() + "," + centroid.getY();
- CoordinateReferenceSystem auto = CRS.decode(code);
-
- MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto);
-
- Polygon projed = (Polygon) JTS.transform(p, transform);
- return Quantities.getQuantity(projed.getArea(), SI.SQUARE_METRE);
- } catch (MismatchedDimensionException | FactoryException | TransformException e) {
- throw new IllegalStateException("Cannot claculate area of feature");
- }
- }
-
- public static void exportToSvg(SimpleFeatureCollection features, Writer out, int width, int height) {
- try {
- double minY = Double.POSITIVE_INFINITY;
- double maxY = Double.NEGATIVE_INFINITY;
- double minX = Double.POSITIVE_INFINITY;
- double maxX = Double.NEGATIVE_INFINITY;
- List<String> shapes = new ArrayList<>();
- for (SimpleFeatureIterator it = features.features(); it.hasNext();) {
- SimpleFeature feature = it.next();
- StringBuffer sb = new StringBuffer();
- sb.append("<polyline style=\"stroke-width:1;stroke:#000000;fill:none;\" points=\"");
-
- Polygon p = (Polygon) feature.getDefaultGeometry();
- Point centroid = p.getCentroid();
- String code = "AUTO:42001," + centroid.getX() + "," + centroid.getY();
- CoordinateReferenceSystem auto = CRS.decode(code);
-
- MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto);
-
- Polygon projed = (Polygon) JTS.transform(p, transform);
-
- for (Coordinate coord : projed.getCoordinates()) {
- double x = coord.x;
- if (x < minX)
- minX = x;
- if (x > maxX)
- maxX = x;
- double y = -coord.y;
- if (y < minY)
- minY = y;
- if (y > maxY)
- maxY = y;
- sb.append(x + "," + y + " ");
- }
- sb.append("\">");
- sb.append("</polyline>\n");
- shapes.add(sb.toString());
-
- }
- double viewportHeight = maxY - minY;
- double viewportWidth = maxX - minX;
- out.write("<svg xmlns=\"http://www.w3.org/2000/svg\"\n");
- out.write(" width=\"" + width + "\"\n");
- out.write(" height=\"" + height + "\"\n");
- out.write(" viewBox=\"" + minX + " " + minY + " " + viewportWidth + " " + viewportHeight + "\"\n");
- out.write(" preserveAspectRatio=\"xMidYMid meet\"\n");
- out.write(">\n");
- for (String shape : shapes) {
- out.write(shape);
- out.write("\n");
- }
- out.write("</svg>");
- } catch (IOException | FactoryException | MismatchedDimensionException | TransformException e) {
- throw new RuntimeException("Cannot export to SVG", e);
- }
- }
-
- /** Write a list of simple features to a shapefile. */
- public static void saveFeaturesAsShapefile(SimpleFeatureType featureType, List<SimpleFeature> features,
- Path shpFile) {
- try {
- ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
-
- Map<String, Serializable> params = new HashMap<>();
- params.put("url", shpFile.toUri().toURL());
-
- params.put("create spatial index", Boolean.TRUE);
-
- ShapefileDataStore newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
- newDataStore.createSchema(featureType);
-
- String typeName = newDataStore.getTypeNames()[0];
- SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName);
- if (featureSource instanceof SimpleFeatureStore) {
- SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
- SimpleFeatureCollection collection = new ListFeatureCollection(featureType, features);
-
- try (Transaction transaction = new DefaultTransaction("create")) {
- try {
- featureStore.setTransaction(transaction);
- featureStore.addFeatures(collection);
- transaction.commit();
- } catch (Exception problem) {
- transaction.rollback();
- throw new RuntimeException("Cannot write shapefile " + shpFile, problem);
- }
- }
- } else {
- throw new IllegalArgumentException(typeName + " does not support read/write access");
- }
- } catch (IOException e) {
- throw new RuntimeException("Cannot write shapefile " + shpFile, e);
- }
- }
-
- /** Singleton. */
- private GeoUtils() {
- }
-}
+++ /dev/null
-package org.argeo.app.geo;
-
-import org.argeo.api.acr.QNamed;
-
-public enum GmlAttr implements QNamed {
- uom
- //
- ;
-
- public final static String UOM_SQUARE_METERS = "m2";
-
- @Override
- public String getNamespace() {
- return "http://www.opengis.net/gml/3.2";
- }
-
- @Override
- public String getDefaultPrefix() {
- return "gml";
- }
-
-}
+++ /dev/null
-package org.argeo.app.geo;
-
-import org.argeo.api.acr.QNamed;
-
-public enum GmlType implements QNamed {
- measure
- //
- ;
-
- @Override
- public String getNamespace() {
- return "http://www.opengis.net/gml/3.2";
- }
-
- @Override
- public String getDefaultPrefix() {
- return "gml";
- }
-
-}
+++ /dev/null
-package org.argeo.app.geo;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.StringTokenizer;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-import org.geotools.data.DataUtilities;
-import org.geotools.feature.SchemaException;
-import org.geotools.feature.simple.SimpleFeatureBuilder;
-import org.geotools.geometry.jts.JTSFactoryFinder;
-import org.locationtech.jts.geom.Coordinate;
-import org.locationtech.jts.geom.GeometryFactory;
-import org.locationtech.jts.geom.Polygon;
-import org.opengis.feature.simple.SimpleFeature;
-import org.opengis.feature.simple.SimpleFeatureType;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-/** Utilities around the GPX format. */
-public class GpxUtils {
-
- public static SimpleFeature parseGpxToPolygon(InputStream in) throws IOException {
- try {
- final SimpleFeatureType TYPE = DataUtilities.createType("Area", "the_geom:Polygon:srid=4326");
- SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
-
- GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
- List<Coordinate> coordinates = new ArrayList<>();
- SAXParserFactory factory = SAXParserFactory.newInstance();
- SAXParser saxParser = factory.newSAXParser();
-
- saxParser.parse(in, new DefaultHandler() {
-
- @Override
- public void startElement(String uri, String localName, String qName, Attributes attributes)
- throws SAXException {
- if ("trkpt".equals(qName)) {
- Double latitude = Double.parseDouble(attributes.getValue("lat"));
- Double longitude = Double.parseDouble(attributes.getValue("lon"));
- Coordinate coordinate = new Coordinate(longitude, latitude);
- coordinates.add(coordinate);
- }
- }
-
- });
- // close the line string
- coordinates.add(coordinates.get(0));
-
- Polygon polygon = geometryFactory.createPolygon(coordinates.toArray(new Coordinate[coordinates.size()]));
- featureBuilder.add(polygon);
- SimpleFeature area = featureBuilder.buildFeature(null);
- return area;
- } catch (ParserConfigurationException | SAXException | SchemaException e) {
- throw new RuntimeException("Cannot convert GPX", e);
- }
- }
-
- public static void writeGeoShapeAsGpx(String geoShape, OutputStream out) throws IOException {
- Objects.requireNonNull(geoShape);
- Writer writer = new OutputStreamWriter(out, StandardCharsets.UTF_8);
- writer.append("<gpx><trk><trkseg>");
- StringTokenizer stSeg = new StringTokenizer(geoShape.trim(), ";");
- while (stSeg.hasMoreTokens()) {
- StringTokenizer stPt = new StringTokenizer(stSeg.nextToken().trim(), " ");
- String lat = stPt.nextToken();
- String lng = stPt.nextToken();
- String alt = stPt.nextToken();
- // String precision = stPt.nextToken();
- writer.append("<trkpt");
- writer.append(" lat=\"").append(lat).append('\"');
- writer.append(" lon=\"").append(lng).append('\"');
- if (!alt.equals("0.0")) {
- writer.append('>');
- writer.append("<ele>").append(alt).append("</ele>");
- writer.append("</trkpt>");
- } else {
- writer.append("/>");
- }
- }
- writer.append("</trkseg></trk></gpx>");
- writer.flush();
- }
-
- /** Singleton. */
- private GpxUtils() {
- }
-}
+++ /dev/null
-package org.argeo.app.geo.geonames;
-
-import java.time.LocalDate;
-import java.time.ZoneId;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-
-/** A Geonames administrative subdivision. */
-public class GeonamesAdm {
- private final Long geonameId;
- private final String countryCode;
- private final String adminCode1;
- private final String admLevel;
- private final Integer level;
- private final String name;
- private final String asciiName;
- private final List<String> alternateNames;
- private final Double lat;
- private final Double lng;
- private final LocalDate lastUpdated;
- private final ZoneId timeZone;
-
- private final Long[] upperLevelIds = new Long[5];
- private final List<GeonamesAdm> upperLevels = new ArrayList<>();
-
- private List<String> row;
-
- /** Initialise from a row in the main Geonames table. */
- public GeonamesAdm(List<String> row) {
- geonameId = Long.parseLong(row.get(0));
- admLevel = row.get(7);
- countryCode = row.get(8);
- adminCode1 = row.get(10);
- if (admLevel.startsWith("ADM")) {
- if (admLevel.endsWith("H"))
- level = Integer.parseInt(admLevel.substring(3, admLevel.length() - 1));
- else
- level = Integer.parseInt(admLevel.substring(3));
- } else if (admLevel.equals("PCLI")) {
- level = 0;
- } else {
- throw new IllegalArgumentException("Unsupported admin level " + admLevel);
- }
- name = row.get(1);
- asciiName = row.get(2);
- alternateNames = Arrays.asList(row.get(3).split(","));
- lat = Double.parseDouble(row.get(4));
- lng = Double.parseDouble(row.get(5));
- lastUpdated = LocalDate.parse(row.get(18));
- timeZone = ZoneId.of(row.get(17));
- // upper levels
- if (row.get(11) != null && !row.get(11).trim().equals(""))
- upperLevelIds[2] = Long.parseLong(row.get(11));
- if (row.get(12) != null && !row.get(12).trim().equals(""))
- upperLevelIds[3] = Long.parseLong(row.get(12));
- if (row.get(13) != null && !row.get(13).trim().equals(""))
- upperLevelIds[4] = Long.parseLong(row.get(13));
- this.row = row;
- }
-
- public void mapUpperLevels(Map<Long, GeonamesAdm> index) {
- for (int i = 0; i < level; i++) {
- Long geonameId = upperLevelIds[i];
- upperLevels.add(i, index.get(geonameId));
- }
- }
-
- public Long getGeonameId() {
- return geonameId;
- }
-
- public Integer getLevel() {
- return level;
- }
-
- public String getName() {
- return name;
- }
-
- public String getName(Function<String, String> transform) {
- if (transform != null)
- return transform.apply(name);
- else
- return name;
-
- }
-
- public String getAsciiName() {
- return asciiName;
- }
-
- public List<String> getAlternateNames() {
- return alternateNames;
- }
-
- public Double getLat() {
- return lat;
- }
-
- public Double getLng() {
- return lng;
- }
-
- public String getCountryCode() {
- return countryCode;
- }
-
- public String getAdmLevel() {
- return admLevel;
- }
-
- public List<String> getRow() {
- return row;
- }
-
- public LocalDate getLastUpdated() {
- return lastUpdated;
- }
-
- public ZoneId getTimeZone() {
- return timeZone;
- }
-
- public String getAdminCode1() {
- return adminCode1;
- }
-
- public Long[] getUpperLevelIds() {
- return upperLevelIds;
- }
-
- public List<GeonamesAdm> getUpperLevels() {
- return upperLevels;
- }
-
- @Override
- public int hashCode() {
- return geonameId.intValue();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof GeonamesAdm))
- return false;
- GeonamesAdm other = (GeonamesAdm) obj;
- return geonameId.equals(other.geonameId);
- }
-
- @Override
- public String toString() {
- return name + " (ADM" + level + " " + geonameId + ")";
- }
-
-}
+++ /dev/null
-package org.argeo.app.geo.geonames;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.argeo.cms.util.CsvParser;
-import org.argeo.cms.util.CsvWriter;
-
-/** Import GeoNames administrative division from the main table. */
-public class ImportGeonamesAdmin {
- // private Log log = LogFactory.getLog(ImportGeonamesAdmin.class);
- private Map<Long, GeonamesAdm> geonamesAdms = new HashMap<>();
-
- /** Loads the data. */
- public void parse(InputStream in) {
- Map<String, Long> countryGeonameIds = new HashMap<>();
- Map<String, Long> admin1GeonameIds = new HashMap<>();
- CsvParser csvParser = new CsvParser() {
-
- @Override
- protected void processLine(Integer lineNumber, List<String> header, List<String> tokens) {
- if (!"A".equals(tokens.get(6)))
- return;
- GeonamesAdm geonamesAdm = new GeonamesAdm(tokens);
- geonamesAdms.put(geonamesAdm.getGeonameId(), geonamesAdm);
- if (geonamesAdm.getAdmLevel().equals("PCLI"))
- countryGeonameIds.put(geonamesAdm.getCountryCode(), geonamesAdm.getGeonameId());
- if (geonamesAdm.getAdmLevel().equals("ADM1"))
- admin1GeonameIds.put(geonamesAdm.getAdminCode1(), geonamesAdm.getGeonameId());
- }
- };
- csvParser.setSeparator('\t');
- csvParser.setNoHeader(true);
- csvParser.parse(in, StandardCharsets.UTF_8);
-
- // fill upper levels
- for (GeonamesAdm adm : geonamesAdms.values()) {
- adm.getUpperLevelIds()[0] = countryGeonameIds.get(adm.getCountryCode());
- if (adm.getLevel() > 0)
- adm.getUpperLevelIds()[1] = admin1GeonameIds.get(adm.getAdminCode1());
- adm.mapUpperLevels(geonamesAdms);
- }
-
- }
-
- public Map<Long, GeonamesAdm> getGeonamesAdms() {
- return geonamesAdms;
- }
-
- /**
- * Copies only the Geonames of feature class 'A' (administrative subdivisions).
- */
- public static void filterGeonamesAdm(InputStream in, OutputStream out) {
- CsvWriter csvWriter = new CsvWriter(out, StandardCharsets.UTF_8);
- csvWriter.setSeparator('\t');
- CsvParser csvParser = new CsvParser() {
-
- @Override
- protected void processLine(Integer lineNumber, List<String> header, List<String> tokens) {
- if (tokens.size() < 7 || !"A".equals(tokens.get(6)))
- return;
- csvWriter.writeLine(tokens);
- }
- };
- csvParser.setSeparator('\t');
- csvParser.setNoHeader(true);
- csvParser.parse(in, StandardCharsets.UTF_8);
- }
-
- public static void main(String[] args) throws IOException {
-// String country = "allCountries";
- String country = "CI";
-// try (InputStream in = Files
-// .newInputStream(Paths.get(System.getProperty("user.home") + "/gis/data/geonames/" + country + ".txt"));
-// OutputStream out = Files.newOutputStream(
-// Paths.get(System.getProperty("user.home") + "/gis/data/geonames/" + country + "-adm.txt"))) {
-// ImportGeonamesAdmin.filterGeonamesAdm(in, out);
-// }
- try (InputStream in = Files.newInputStream(
- Paths.get(System.getProperty("user.home") + "/gis/data/geonames/" + country + "-adm.txt"))) {
- ImportGeonamesAdmin importGeonamesAdmin = new ImportGeonamesAdmin();
- importGeonamesAdmin.parse(in);
- }
- }
-
-}
--- /dev/null
+package org.argeo.app.ux.js;
+
+import java.util.Optional;
+
+public abstract class AbstractJsObject {
+ /**
+ * JavaScript expression returning a reference to the object. It can be either a
+ * variable or a function call. If it is not set the object is assumed to be a
+ * new.
+ */
+ private String reference;
+
+ private JsClient jsClient;
+
+ private Object[] jsConstructorArgs;
+
+// public AbstractJsObject(JsClient jsClient, String reference) {
+// Objects.requireNonNull(jsClient);
+// Objects.requireNonNull(reference, "JS reference cannot be null");
+// this.jsClient = jsClient;
+// this.reference = reference;
+// }
+
+ public AbstractJsObject(Object... args) {
+ if (args.length == 2 && args[0] instanceof JsClient jsClient) {
+ this.jsClient = jsClient;
+ this.reference = args[1].toString();
+ } else {
+ this.jsConstructorArgs = args;
+ }
+ }
+
+ public abstract String getJsPackage();
+
+ public void create(JsClient jsClient, String varName) {
+ if (!isNew())
+ throw new IllegalStateException("JS object " + getJsClassName() + " is not new");
+ if (isFunctionReference())
+ throw new IllegalStateException(
+ "JS object " + getJsClassName() + " cannot be created since it is a function reference");
+ jsClient.execute(jsClient.getJsVarName(varName) + " = " + newJs() + ";");
+ reference = varName;
+ this.jsClient = jsClient;
+ }
+
+ public void delete() {
+ if (isNew())
+ throw new IllegalStateException(
+ "JS object " + getJsClassName() + " cannot be deleted since it is anonymous");
+ if (isFunctionReference())
+ throw new IllegalStateException(
+ "JS object " + getJsClassName() + " cannot be deleted since it is a function reference");
+ jsClient.execute(reference + " = undefined; delete " + reference + ";");
+ }
+
+ public boolean isNew() {
+ return reference == null;
+ }
+
+ public boolean isFunctionReference() {
+ return !isNew() && !getReference().endsWith(")");
+ }
+
+ public String getReference() {
+ return reference;
+ }
+
+ protected String getJsReference() {
+ return jsClient.getJsVarName(reference);
+ }
+
+ protected String newJs() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("new ");
+ sb.append(getJsClassName());
+ sb.append("(");
+ sb.append(JsClient.toJsArgs(jsConstructorArgs));
+ sb.append(")");
+ return sb.toString();
+ }
+
+ public String getJsClassName() {
+ return getJsPackage() + "." + getClass().getSimpleName();
+ }
+
+ public Object callMethod(String methodName, Object... args) {
+ return jsClient.callMethod(getJsReference(), methodName + "(" + JsClient.toJsArgs(args) + ")");
+ }
+
+ public void executeMethod(String methodName, Object... args) {
+ jsClient.executeMethod(getJsReference(), methodName + "(" + JsClient.toJsArgs(args) + ")");
+ }
+
+ protected String getMethodName() {
+ StackWalker walker = StackWalker.getInstance();
+ Optional<String> methodName = walker.walk(frames -> {
+ return frames.skip(1).findFirst().map(StackWalker.StackFrame::getMethodName);
+ });
+ return methodName.orElseThrow();
+ }
+
+ protected JsClient getJsClient() {
+ return jsClient;
+ }
+
+ protected Object[] getJsConstructorArgs() {
+ return jsConstructorArgs;
+ }
+
+ protected void setJsConstructorArgs(Object[] jsConstructorArgs) {
+ this.jsConstructorArgs = jsConstructorArgs;
+ }
+
+}
--- /dev/null
+package org.argeo.app.ux.js;
+
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringJoiner;
+import java.util.concurrent.CompletionStage;
+import java.util.function.Function;
+
+/**
+ * A remote JavaScript view (typically in a web browser) which is tightly
+ * integrated with a local UX part.
+ */
+public interface JsClient {
+
+ /*
+ * TO IMPLEMENT
+ */
+
+ /**
+ * Execute this JavaScript on the client side after making sure that the page
+ * has been loaded and the map object has been created.
+ *
+ * @param js the JavaScript code, possibly formatted according to
+ * {@link String#format}, with {@link Locale#ROOT} as locale (for
+ * stability of decimal separator, as expected by JavaScript.
+ * @param args the optional arguments of
+ * {@link String#format(String, Object...)}
+ */
+ Object evaluate(String js, Object... args);
+
+ /**
+ * Executes this JavaScript without expecting a return value.
+ *
+ * @param js the JavaScript code, possibly formatted according to
+ * {@link String#format}, with {@link Locale#ROOT} as locale (for
+ * stability of decimal separator, as expected by JavaScript.
+ * @param args the optional arguments of
+ * {@link String#format(String, Object...)}
+ */
+ void execute(String js, Object... args);
+
+ /** @return the globally usable function name. */
+ String createJsFunction(String name, Function<Object[], Object> toDo);
+
+ /** Get a global variable name. */
+ String getJsVarName(String name);
+
+ /**
+ * Completion stage when the client is ready (typically the page has loaded in
+ * the browser).
+ */
+ CompletionStage<Boolean> getReadyStage();
+
+ /*
+ * DEFAULTS
+ */
+
+ default Object callMethod(String jsObject, String methodCall, Object... args) {
+ return evaluate(jsObject + '.' + methodCall, args);
+ }
+
+ default void executeMethod(String jsObject, String methodCall, Object... args) {
+ execute(jsObject + '.' + methodCall, args);
+ }
+
+ default boolean isInstanceOf(String reference, String jsClass) {
+ return (Boolean) evaluate("return "+getJsVarName(reference) + " instanceof " + jsClass);
+ }
+
+ /*
+ * UTILITIES
+ */
+
+ static String toJsValue(Object o) {
+ if (o instanceof CharSequence)
+ return '\'' + o.toString() + '\'';
+ else if (o instanceof Number)
+ return o.toString();
+ else if (o instanceof Boolean)
+ return o.toString();
+ else if (o instanceof Map map)
+ return toJsMap(map);
+ else if (o instanceof Object[] arr)
+ return toJsArray(arr);
+ else if (o instanceof int[] arr)
+ return toJsArray(arr);
+ else if (o instanceof long[] arr)
+ return toJsArray(arr);
+ else if (o instanceof double[] arr)
+ return toJsArray(arr);
+ else if (o instanceof AbstractJsObject jsObject) {
+ if (jsObject.isNew())
+ return jsObject.newJs();
+ else
+ return jsObject.getJsReference();
+ } else if (o instanceof JsReference jsReference) {
+ return jsReference.get();
+ } else
+ return '\'' + o.toString() + '\'';
+ }
+
+ static String toJsArgs(Object... arr) {
+ StringJoiner sj = new StringJoiner(",");
+ for (Object o : arr) {
+ sj.add(toJsValue(o));
+ }
+ return sj.toString();
+ }
+
+ static String toJsArray(Object... arr) {
+ StringJoiner sj = new StringJoiner(",", "[", "]");
+ for (Object o : arr) {
+ sj.add(toJsValue(o));
+ }
+ return sj.toString();
+ }
+
+ static String toJsArray(String... arr) {
+ return toJsArray((Object[]) arr);
+ }
+
+ static String toJsArray(double... arr) {
+ return Arrays.toString(arr);
+ }
+
+ static String toJsArray(long... arr) {
+ return Arrays.toString(arr);
+ }
+
+ static String toJsArray(int... arr) {
+ return Arrays.toString(arr);
+ }
+
+ static String toJsMap(Map<?, ?> map) {
+ StringJoiner sj = new StringJoiner(",", "{", "}");
+ // TODO escape forbidden characters
+ for (Object key : map.keySet()) {
+ sj.add("'" + key + "':" + toJsValue(map.get(key)));
+ }
+ return sj.toString();
+ }
+
+ static String escapeQuotes(String str) {
+ return str.replace("'", "\\'").replace("\"", "\\\"");
+ }
+
+}
--- /dev/null
+package org.argeo.app.ux.js;
+
+import java.util.function.Supplier;
+
+/** Plain JS reference, to be directly serialised. */
+public class JsReference implements Supplier<String> {
+ private final String reference;
+
+ public JsReference(String reference) {
+ this.reference = reference;
+ }
+
+ public String get() {
+ return reference;
+ }
+
+}
/** Called when a user has received a new form submission. */
public interface FormSubmissionListener {
+ final static String XML_SUBMISSION_FILE = "xml_submission_file";
+
/**
* Called after a form submission has been stored in the user area. The
* submission will be deleted if any exception is thrown.
*/
- void formSubmissionReceived(Content content);
+ void formSubmissionReceived(Content content, boolean isIncomplete);
}
- * (STRING)
+ xforms:label (jcrx:xmlvalue) = jcrx:xmlvalue
+ xforms:hint (jcrx:xmlvalue) = jcrx:xmlvalue *
++ xforms:setvalue (xforms:setvalue) = xforms:setvalue *
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.app.geo</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
--- /dev/null
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
+org.eclipse.jdt.core.compiler.compliance=17
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=17
--- /dev/null
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true">
+ <implementation class="org.argeo.app.geo.http.WfsHttpHandler"/>
+ <service>
+ <provide interface="com.sun.net.httpserver.HttpHandler"/>
+ </service>
+ <property name="context.path" type="String" value="/api/wfs/" />
+ <reference bind="setContentRepository" cardinality="1..1" interface="org.argeo.api.acr.spi.ProvidedRepository" name="ProvidedRepository" policy="static"/>
+ <reference bind="addFeatureAdapter" cardinality="0..n" interface="org.argeo.app.api.geo.FeatureAdapter" name="FeatureAdapter" policy="dynamic" unbind="removeFeatureAdapter"/>
+</scr:component>
--- /dev/null
+Import-Package:\
+tech.units.indriya.unit,\
+com.fasterxml.jackson.core,\
+org.geotools.xml.transform,\
+*
+
+Service-Component:\
+OSGI-INF/wfsHttpHandler.xml,\
--- /dev/null
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
--- /dev/null
+package org.argeo.app.api.geo;
+
+import javax.xml.namespace.QName;
+
+import org.argeo.api.acr.Content;
+import org.argeo.api.acr.search.AndFilter;
+import org.argeo.app.api.EntityType;
+import org.argeo.app.geo.acr.GeoEntityUtils;
+import org.locationtech.jts.geom.Geometry;
+
+import jakarta.json.stream.JsonGenerator;
+
+public interface FeatureAdapter {
+ default Geometry getDefaultGeometry(Content c, QName targetFeature) {
+ // TODO deal with more defaults
+ // TODO deal with target feature
+ if (c.hasContentClass(EntityType.geopoint)) {
+ return getGeoPointGeometry(c);
+ }
+ return null;
+ }
+
+ void writeProperties(JsonGenerator g, Content content, QName targetFeature);
+
+ void addConstraintsForFeature(AndFilter filter, QName targetFeature);
+
+ static Geometry getGeoPointGeometry(Content c) {
+ if (c.hasContentClass(EntityType.geopoint)) {
+ return GeoEntityUtils.toPoint(c);
+// double latitude = c.get(WGS84PosName.lat, Double.class).get();
+// double longitude = c.get(WGS84PosName.lon, Double.class).get();
+//
+// Coordinate coordinate = new Coordinate(longitude, latitude);
+// Point the_geom = JTS.GEOMETRY_FACTORY.createPoint(coordinate);
+// return the_geom;
+ }
+ return null;
+ }
+}
--- /dev/null
+package org.argeo.app.api.geo;
+
+/** Keys used for WFS KVP (key-value pair) encoding. */
+public enum WfsKvp {
+ CQL_FILTER("cql_filter"), //
+ OUTPUT_FORMAT("outputFormat"), //
+ TYPE_NAMES("typeNames"), //
+ BBOX("bbox"), //
+ FORMAT_OPTIONS("format_options"), //
+ ;
+
+ public final static String FILENAME_ = "filename:";
+
+ private final String key;
+
+ private WfsKvp(String key) {
+ this.key = key;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+}
--- /dev/null
+package org.argeo.app.geo;
+
+import org.argeo.api.acr.NamespaceUtils;
+import org.argeo.api.acr.search.AndFilter;
+import org.argeo.api.acr.search.BasicSearch;
+import org.argeo.api.acr.search.ContentFilter;
+import org.geotools.api.filter.And;
+import org.geotools.api.filter.Filter;
+import org.geotools.api.filter.PropertyIsEqualTo;
+import org.geotools.api.filter.expression.Literal;
+import org.geotools.api.filter.expression.PropertyName;
+import org.geotools.filter.text.cql2.CQL;
+import org.geotools.filter.text.cql2.CQLException;
+
+/** Utilities around the CQL query format. */
+public class CqlUtils {
+
+ public static void filter(BasicSearch search, String cql) {
+ try {
+ filter(search, CQL.toFilter(cql));
+ } catch (CQLException e) {
+ throw new IllegalArgumentException("Cannot parse CQL: " + cql, e);
+ }
+ }
+
+ public static void filter(BasicSearch search, Filter filter) {
+ search.where((where) -> {
+ if (filter instanceof And and) {
+ processAnd(where, and);
+ } else if (filter instanceof PropertyIsEqualTo propertyIsEqualTo) {
+ processIsEqualTo(where, propertyIsEqualTo);
+ } else {
+ throw new IllegalArgumentException("Unsupported filter " + filter.getClass());
+ }
+ });
+ }
+
+ private static void processAnd(AndFilter contentFilter, And filter) {
+ for (Filter child : filter.getChildren()) {
+ if (child instanceof PropertyIsEqualTo propertyIsEqualTo) {
+ processIsEqualTo(contentFilter, propertyIsEqualTo);
+ }
+ }
+
+ }
+
+ private static void processIsEqualTo(ContentFilter<?> contentFilter, PropertyIsEqualTo propertyIsEqualTo) {
+ // TODO properly deal with types etc.
+ // see GeoTools org.geotools.filter.text.commons.ExpressionToText
+ PropertyName propertyName = (PropertyName) propertyIsEqualTo.getExpression1();
+ Literal value = (Literal) propertyIsEqualTo.getExpression2();
+ // String escaped = literal.toString().replaceAll("'", "''");
+ contentFilter.eq(NamespaceUtils.parsePrefixedName(propertyName.toString()), value.toString());
+ }
+
+ /** singleton */
+ private CqlUtils() {
+ }
+}
--- /dev/null
+package org.argeo.app.geo;
+
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.Envelope;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.GeometryCollection;
+import org.locationtech.jts.geom.LineString;
+import org.locationtech.jts.geom.LinearRing;
+import org.locationtech.jts.geom.MultiPoint;
+import org.locationtech.jts.geom.Point;
+import org.locationtech.jts.geom.Polygon;
+
+import jakarta.json.JsonArray;
+import jakarta.json.JsonObject;
+import jakarta.json.stream.JsonGenerator;
+
+/**
+ * GeoJSon format.
+ *
+ * @see https://datatracker.ietf.org/doc/html/rfc7946
+ */
+public class GeoJson {
+ public final static String POINT_TYPE = "Point";
+ public final static String MULTI_POINT_TYPE = "MultiPoint";
+ public final static String LINE_STRING_TYPE = "LineString";
+ public final static String POLYGON_TYPE = "Polygon";
+ public final static String GEOMETRY_COLLECTION_TYPE = "GeometryCollection";
+
+ public final static String TYPE = "type";
+ public final static String GEOMETRY = "geometry";
+ public final static String GEOMETRIES = "geometries";
+ public final static String COORDINATES = "coordinates";
+ public final static String BBOX = "bbox";
+ public final static String PROPERTIES = "properties";
+
+ /*
+ * WRITE
+ */
+ /** Writes a {@link Geometry} as GeoJSON. */
+ public static void writeGeometry(JsonGenerator g, Geometry geometry) {
+ if (geometry instanceof Point point) {
+ g.write(TYPE, POINT_TYPE);
+ g.writeStartArray(COORDINATES);
+ writeCoordinate(g, point.getCoordinate());
+ g.writeEnd();// coordinates array
+ } else if (geometry instanceof MultiPoint multiPoint) {
+ g.write(TYPE, MULTI_POINT_TYPE);
+ g.writeStartArray(COORDINATES);
+ writeCoordinates(g, multiPoint.getCoordinates());
+ g.writeEnd();// coordinates array
+ } else if (geometry instanceof LineString lineString) {
+ g.write(TYPE, LINE_STRING_TYPE);
+ g.writeStartArray(COORDINATES);
+ writeCoordinates(g, lineString.getCoordinates());
+ g.writeEnd();// coordinates array
+ } else if (geometry instanceof Polygon polygon) {
+ g.write(TYPE, POLYGON_TYPE);
+ g.writeStartArray(COORDINATES);
+ LinearRing exteriorRing = polygon.getExteriorRing();
+ g.writeStartArray();
+ writeCoordinates(g, exteriorRing.getCoordinates());
+ g.writeEnd();
+ for (int i = 0; i < polygon.getNumInteriorRing(); i++) {
+ LinearRing interiorRing = polygon.getInteriorRingN(i);
+ // TODO verify that holes are clockwise
+ g.writeStartArray();
+ writeCoordinates(g, interiorRing.getCoordinates());
+ g.writeEnd();
+ }
+ g.writeEnd();// coordinates array
+ } else if (geometry instanceof GeometryCollection geometryCollection) {// must be last
+ g.write(TYPE, GEOMETRY_COLLECTION_TYPE);
+ g.writeStartArray(GEOMETRIES);
+ for (int i = 0; i < geometryCollection.getNumGeometries(); i++) {
+ g.writeStartObject();
+ writeGeometry(g, geometryCollection.getGeometryN(i));
+ g.writeEnd();// geometry object
+ }
+ g.writeEnd();// geometries array
+ } else {
+ throw new IllegalArgumentException(geometry.getClass() + " is not supported.");
+ }
+ }
+
+ /** Writes a sequence of coordinates [[lat,lon],[lat,lon]] */
+ public static void writeCoordinates(JsonGenerator g, Coordinate[] coordinates) {
+ for (Coordinate coordinate : coordinates) {
+ g.writeStartArray();
+ writeCoordinate(g, coordinate);
+ g.writeEnd();
+ }
+ }
+
+ /** Writes a pair of coordinates [lat,lon]. */
+ public static void writeCoordinate(JsonGenerator g, Coordinate coordinate) {
+ // !! longitude is first in GeoJSON
+ g.write(coordinate.getY());
+ g.write(coordinate.getX());
+ double z = coordinate.getZ();
+ if (!Double.isNaN(z)) {
+ g.write(z);
+ }
+ }
+
+ /**
+ * Writes the {@link Envelope} of a {@link Geometry} as a bbox GeoJSON object.
+ */
+ public static void writeBBox(JsonGenerator g, Geometry geometry) {
+ g.writeStartArray(BBOX);
+ Envelope envelope = geometry.getEnvelopeInternal();
+ g.write(envelope.getMinX());
+ g.write(envelope.getMinY());
+ g.write(envelope.getMaxX());
+ g.write(envelope.getMaxY());
+ g.writeEnd();
+ }
+
+ /*
+ * READ
+ */
+ /** Reads a geometry from the geometry object of a GEoJSON feature. */
+ @SuppressWarnings("unchecked")
+ public static <T extends Geometry> T readGeometry(JsonObject geom, Class<T> clss) {
+ String type = geom.getString(TYPE);
+ JsonArray coordinates = geom.getJsonArray(COORDINATES);
+ Geometry res = switch (type) {
+ case POINT_TYPE: {
+ Coordinate coord = readCoordinate(coordinates);
+ yield JTS.GEOMETRY_FACTORY_WGS84.createPoint(coord);
+ }
+ case LINE_STRING_TYPE: {
+ Coordinate[] coords = readCoordinates(coordinates);
+ yield JTS.GEOMETRY_FACTORY_WGS84.createLineString(coords);
+ }
+ case POLYGON_TYPE: {
+ assert coordinates.size() > 0;
+ LinearRing exterior = JTS.GEOMETRY_FACTORY_WGS84
+ .createLinearRing(readCoordinates(coordinates.getJsonArray(0)));
+ LinearRing[] holes = new LinearRing[coordinates.size() - 1];
+ for (int i = 0; i < coordinates.size() - 1; i++) {
+ holes[i] = JTS.GEOMETRY_FACTORY_WGS84
+ .createLinearRing(readCoordinates(coordinates.getJsonArray(i + 1)));
+ }
+ yield JTS.GEOMETRY_FACTORY_WGS84.createPolygon(exterior, holes);
+ }
+ default:
+ throw new IllegalArgumentException("Unexpected value: " + type);
+ };
+// res.normalize();
+ return (T) res;
+ }
+
+ /** Reads a coordinate pair [lon,lat]. */
+ public static Coordinate readCoordinate(JsonArray arr) {
+ assert arr.size() >= 2;
+ // !! longitude is first in GeoJSon
+ return new Coordinate(arr.getJsonNumber(1).doubleValue(), arr.getJsonNumber(0).doubleValue());
+ }
+
+ /** Reads a coordinate sequence [[lon,lat],[lon,lat]]. */
+ public static Coordinate[] readCoordinates(JsonArray arr) {
+ Coordinate[] coords = new Coordinate[arr.size()];
+ for (int i = 0; i < arr.size(); i++)
+ coords[i] = readCoordinate(arr.getJsonArray(i));
+ return coords;
+ }
+
+ /** singleton */
+ private GeoJson() {
+ }
+
+}
--- /dev/null
+package org.argeo.app.geo;
+
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/** Geo data utilities. */
+public class GeoJsonUtils {
+
+ /** Add these properties to all features. */
+ public static void addProperties(JsonNode tree, Map<String, String> map) {
+ for (JsonNode feature : tree.get("features")) {
+ ObjectNode properties = (ObjectNode) feature.get("properties");
+ for (String key : map.keySet()) {
+ properties.put(key, map.get(key));
+ }
+ }
+ }
+
+ /** Singleton. */
+ private GeoJsonUtils() {
+ }
+}
--- /dev/null
+package org.argeo.app.geo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.StringTokenizer;
+
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.GeometryFactory;
+import org.locationtech.jts.geom.LineString;
+import org.locationtech.jts.geom.MultiPoint;
+import org.locationtech.jts.geom.Point;
+import org.locationtech.jts.geom.Polygon;
+
+/** Utilities around ODK's GeoShape format */
+public class GeoShapeUtils {
+
+ @SuppressWarnings("unchecked")
+ public static <T> T geoShapeToGeometry(String geoShape, Class<T> clss) {
+ Objects.requireNonNull(geoShape);
+ GeometryFactory geometryFactory = JTS.GEOMETRY_FACTORY_WGS84;
+ List<Coordinate> coordinates = new ArrayList<>();
+ StringTokenizer stSeg = new StringTokenizer(geoShape.trim(), ";");
+ while (stSeg.hasMoreTokens()) {
+ StringTokenizer stPt = new StringTokenizer(stSeg.nextToken().trim(), " ");
+ String lat = stPt.nextToken();
+ String lng = stPt.nextToken();
+ String alt = stPt.nextToken();
+ // String precision = stPt.nextToken();
+ Coordinate coord;
+ if (!alt.equals("0.0")) {
+ coord = new Coordinate(Double.parseDouble(lat), Double.parseDouble(lng), Double.parseDouble(alt));
+ } else {
+ coord = new Coordinate(Double.parseDouble(lat), Double.parseDouble(lng));
+ }
+ coordinates.add(coord);
+ }
+ if (LineString.class.isAssignableFrom(clss)) {
+ LineString lineString = geometryFactory
+ .createLineString(coordinates.toArray(new Coordinate[coordinates.size()]));
+ return (T) lineString;
+ } else if (MultiPoint.class.isAssignableFrom(clss)) {
+ MultiPoint multiPoint = geometryFactory
+ .createMultiPointFromCoords(coordinates.toArray(new Coordinate[coordinates.size()]));
+ return (T) multiPoint;
+ } else if (Polygon.class.isAssignableFrom(clss)) {
+ Coordinate first = coordinates.get(0);
+ Coordinate last = coordinates.get(coordinates.size() - 1);
+ if (!(first.getX() == last.getX() && first.getY() == last.getY())) {
+ // close the line string
+ coordinates.add(first);
+ }
+ Polygon polygon = geometryFactory.createPolygon(coordinates.toArray(new Coordinate[coordinates.size()]));
+ return (T) polygon;
+ } else {
+ throw new IllegalArgumentException("Unsupported format " + clss);
+ }
+ }
+
+ /** Converts a {@link Geometry} with WGS84 coordinates to a GeoShape. */
+ public static String geometryToGeoShape(Geometry geometry) {
+ if (geometry instanceof Point point) {
+ Coordinate coordinate = point.getCoordinate();
+ StringBuilder sb = new StringBuilder();
+ appendToGeoShape(sb, coordinate.getX(), coordinate.getY(), coordinate.getZ());
+ return sb.toString();
+ } else if (geometry instanceof Polygon || geometry instanceof LineString) {
+ StringBuilder sb = new StringBuilder();
+ for (Coordinate coordinate : geometry.getCoordinates()) {
+ appendToGeoShape(sb, coordinate.getX(), coordinate.getY(), coordinate.getZ());
+ sb.append(';');
+ }
+ return sb.toString();
+ } else {
+ throw new IllegalArgumentException("Unsupported geometry " + geometry.getClass());
+ }
+ }
+
+ public static String geoPointToGeoShape(double lon, double lat, double alt) {
+ StringBuilder sb = new StringBuilder();
+ appendToGeoShape(sb, lon, lat, alt);
+ return sb.toString();
+ }
+
+ private static void appendToGeoShape(StringBuilder sb, double lon, double lat, double alt) {
+ sb.append(lat).append(' ');
+ sb.append(lon).append(' ');
+ if (alt != Double.NaN)
+ sb.append(alt).append(' ');
+ else
+ sb.append("0 ");
+ sb.append('0');
+ }
+
+ /** singleton */
+ private GeoShapeUtils() {
+ }
+
+}
--- /dev/null
+package org.argeo.app.geo;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/** Converts a geographical feature to an SVG. */
+public class GeoToSvg {
+ public void convertGeoJsonToSvg(Path source, Path target) {
+ ObjectMapper objectMapper = new ObjectMapper();
+ try (InputStream in = Files.newInputStream(source);
+ Writer out = Files.newBufferedWriter(target, StandardCharsets.UTF_8)) {
+ JsonNode tree = objectMapper.readTree(in);
+ JsonNode coord = tree.get("features").get(0).get("geometry").get("coordinates");
+ double ratio = 100;
+ double minX = Double.POSITIVE_INFINITY;
+ double maxX = Double.NEGATIVE_INFINITY;
+ double minY = Double.POSITIVE_INFINITY;
+ double maxY = Double.NEGATIVE_INFINITY;
+ List<String> shapes = new ArrayList<>();
+ for (JsonNode shape : coord) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("<polyline style=\"stroke-width:0.00000003;stroke:#000000;\" points=\"");
+ for (JsonNode latlng : shape) {
+ double lat = latlng.get(0).asDouble();
+ double y = lat * ratio;
+ if (y < minY)
+ minY = y;
+ if (y > maxY)
+ maxY = y;
+ double lng = latlng.get(1).asDouble();
+ double x = lng * ratio;
+ if (x < minX)
+ minX = x;
+ if (x > maxX)
+ maxX = x;
+ sb.append(y + "," + x + " ");
+ }
+ sb.append("\">");
+ sb.append("</polyline>\n");
+ shapes.add(sb.toString());
+ }
+
+ double width = maxX - minX;
+ double height = maxY - minY;
+ out.write("<svg xmlns=\"http://www.w3.org/2000/svg\"\n");
+ out.write(" width=\"" + (int) (width * 1000) + "\"\n");
+ out.write(" height=\"" + (int) (height * 1000) + "\"\n");
+ out.write(" viewBox=\"" + minX + "," + minY + "," + width + "," + height + "\"\n");
+ out.write(">\n");
+ for (String shape : shapes) {
+ out.write(shape);
+ out.write("\n");
+ }
+ out.write("</svg>");
+ } catch (IOException e) {
+ throw new RuntimeException("Cannot convert " + source + " to " + target, e);
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.app.geo;
+
+import org.argeo.api.cms.CmsLog;
+import org.geotools.api.filter.FilterFactory;
+import org.geotools.api.style.StyleFactory;
+import org.geotools.factory.CommonFactoryFinder;
+
+/**
+ * Factories initialisation and workarounds for the GeoTools library. The idea
+ * is to code defensively around factory initialisation, API changes, and issues
+ * related to running in an OSGi environment. Rather see {@link GeoUtils} for
+ * functional static utilities.
+ */
+public class GeoTools {
+ private final static CmsLog log = CmsLog.getLog(GeoTools.class);
+
+ public final static StyleFactory STYLE_FACTORY;
+ public final static FilterFactory FILTER_FACTORY;
+
+ static {
+ try {
+ STYLE_FACTORY = CommonFactoryFinder.getStyleFactory();
+ FILTER_FACTORY = CommonFactoryFinder.getFilterFactory();
+ } catch (RuntimeException e) {
+ log.error("Basic GeoTools initialisation failed, geographical utilities are probably not available", e);
+ throw e;
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.app.geo;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.geotools.api.data.SimpleFeatureSource;
+import org.geotools.api.data.SimpleFeatureStore;
+import org.geotools.api.data.Transaction;
+import org.geotools.api.feature.simple.SimpleFeature;
+import org.geotools.api.feature.simple.SimpleFeatureType;
+import org.geotools.data.DataUtilities;
+import org.geotools.data.DefaultTransaction;
+import org.geotools.data.collection.ListFeatureCollection;
+import org.geotools.data.shapefile.ShapefileDataStore;
+import org.geotools.data.shapefile.ShapefileDataStoreFactory;
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.geometry.jts.JTSFactoryFinder;
+import org.geotools.swing.data.JFileDataStoreChooser;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.GeometryFactory;
+import org.locationtech.jts.geom.LineString;
+import org.locationtech.jts.geom.Point;
+
+public class GeoToolsTest {
+ public GeoToolsTest() {
+
+ }
+
+ public void init() {
+ try {
+ main(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void destroy() {
+
+ }
+
+ public static void main(String[] args) throws Exception {
+ final SimpleFeatureType TYPE = DataUtilities.createType("Location", "the_geom:Point:srid=4326," + // <- the
+ // geometry
+ // attribute:
+ // Point
+ // type
+ "name:String," + // <- a String attribute
+ "number:Integer" // a number attribute
+ );
+ final SimpleFeatureType TYPE_HULL = DataUtilities.createType("Hull", "the_geom:MultiPolygon:srid=4326");
+ System.out.println("TYPE:" + TYPE);
+
+ /*
+ * A list to collect features as we create them.
+ */
+ List<SimpleFeature> features = new ArrayList<>();
+ List<Coordinate> coordinates = new ArrayList<>();
+
+ /*
+ * GeometryFactory will be used to create the geometry attribute of each
+ * feature, using a Point object for the location.
+ */
+ GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
+
+ SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
+
+ try (BufferedReader reader = new BufferedReader(
+ new InputStreamReader(GeoToolsTest.class.getResourceAsStream("/org/djapps/on/apaf/locations.csv")))) {
+ /* First line of the data file is the header */
+ String line = reader.readLine();
+ System.out.println("Header: " + line);
+
+ for (line = reader.readLine(); line != null; line = reader.readLine()) {
+ if (line.trim().length() > 0) { // skip blank lines
+ String[] tokens = line.split("\\,");
+
+ double latitude = Double.parseDouble(tokens[0]);
+ double longitude = Double.parseDouble(tokens[1]);
+ String name = tokens[2].trim();
+ int number = Integer.parseInt(tokens[3].trim());
+
+ /* Longitude (= x coord) first ! */
+ Coordinate coordinate = new Coordinate(longitude, latitude);
+ coordinates.add(coordinate);
+ Point point = geometryFactory.createPoint(coordinate);
+
+ featureBuilder.add(point);
+ featureBuilder.add(name);
+ featureBuilder.add(number);
+ SimpleFeature feature = featureBuilder.buildFeature(null);
+ features.add(feature);
+ }
+ }
+ }
+
+ LineString lineString = geometryFactory
+ .createLineString(coordinates.toArray(new Coordinate[coordinates.size()]));
+ Geometry convexHull = lineString.convexHull();
+ System.out.println(convexHull.toText());
+ SimpleFeatureBuilder hullFeatureBuilder = new SimpleFeatureBuilder(TYPE_HULL);
+ hullFeatureBuilder.add(convexHull);
+ SimpleFeature hull = hullFeatureBuilder.buildFeature(null);
+
+ /*
+ * Get an output file name and create the new shapefile
+ */
+ File newFile = getNewShapeFile();
+
+ ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
+
+ Map<String, Serializable> params = new HashMap<>();
+ params.put("url", newFile.toURI().toURL());
+ params.put("create spatial index", Boolean.TRUE);
+
+ ShapefileDataStore newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
+
+ /*
+ * TYPE is used as a template to describe the file contents
+ */
+ newDataStore.createSchema(TYPE_HULL);
+
+ /*
+ * Write the features to the shapefile
+ */
+ Transaction transaction = new DefaultTransaction("create");
+
+ String typeName = newDataStore.getTypeNames()[0];
+ SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName);
+ SimpleFeatureType SHAPE_TYPE = featureSource.getSchema();
+ /*
+ * The Shapefile format has a couple limitations: - "the_geom" is always first,
+ * and used for the geometry attribute name - "the_geom" must be of type Point,
+ * MultiPoint, MuiltiLineString, MultiPolygon - Attribute names are limited in
+ * length - Not all data types are supported (example Timestamp represented as
+ * Date)
+ *
+ * Each data store has different limitations so check the resulting
+ * SimpleFeatureType.
+ */
+ System.out.println("SHAPE:" + SHAPE_TYPE);
+
+ if (featureSource instanceof SimpleFeatureStore) {
+ SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
+ /*
+ * SimpleFeatureStore has a method to add features from a
+ * SimpleFeatureCollection object, so we use the ListFeatureCollection class to
+ * wrap our list of features.
+ */
+ SimpleFeatureCollection collection = new ListFeatureCollection(TYPE, Collections.singletonList(hull));
+ featureStore.setTransaction(transaction);
+ try {
+ featureStore.addFeatures(collection);
+ transaction.commit();
+ } catch (Exception problem) {
+ problem.printStackTrace();
+ transaction.rollback();
+ } finally {
+ transaction.close();
+ }
+ } else {
+ System.out.println(typeName + " does not support read/write access");
+ }
+// if (featureSource instanceof SimpleFeatureStore) {
+// SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
+// /*
+// * SimpleFeatureStore has a method to add features from a
+// * SimpleFeatureCollection object, so we use the ListFeatureCollection class to
+// * wrap our list of features.
+// */
+// SimpleFeatureCollection collection = new ListFeatureCollection(TYPE, features);
+// featureStore.setTransaction(transaction);
+// try {
+// featureStore.addFeatures(collection);
+// transaction.commit();
+// } catch (Exception problem) {
+// problem.printStackTrace();
+// transaction.rollback();
+// } finally {
+// transaction.close();
+// }
+// } else {
+// System.out.println(typeName + " does not support read/write access");
+// }
+ }
+
+ /**
+ * Prompt the user for the name and path to use for the output shapefile
+ *
+ * @param csvFile the input csv file used to create a default shapefile name
+ * @return name and path for the shapefile as a new File object
+ */
+ private static File getNewShapeFile() {
+// String path = csvFile.getAbsolutePath();
+// String newPath = path.substring(0, path.length() - 4) + ".shp";
+
+ JFileDataStoreChooser chooser = new JFileDataStoreChooser("shp");
+ chooser.setDialogTitle("Save shapefile");
+// chooser.setSelectedFile(new File(newPath));
+
+ int returnVal = chooser.showSaveDialog(null);
+
+ if (returnVal != JFileDataStoreChooser.APPROVE_OPTION) {
+ // the user cancelled the dialog
+ System.exit(0);
+ }
+
+ File newFile = chooser.getSelectedFile();
+
+ return newFile;
+ }
+
+}
--- /dev/null
+package org.argeo.app.geo;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.Writer;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import javax.measure.Quantity;
+import javax.measure.quantity.Area;
+import javax.xml.transform.TransformerException;
+
+import org.geotools.api.data.SimpleFeatureSource;
+import org.geotools.api.data.SimpleFeatureStore;
+import org.geotools.api.data.Transaction;
+import org.geotools.api.feature.simple.SimpleFeature;
+import org.geotools.api.feature.simple.SimpleFeatureType;
+import org.geotools.api.filter.Filter;
+import org.geotools.api.filter.FilterFactory;
+import org.geotools.api.filter.expression.Expression;
+import org.geotools.api.geometry.MismatchedDimensionException;
+import org.geotools.api.referencing.FactoryException;
+import org.geotools.api.referencing.crs.CoordinateReferenceSystem;
+import org.geotools.api.referencing.operation.MathTransform;
+import org.geotools.api.referencing.operation.TransformException;
+import org.geotools.api.style.AnchorPoint;
+import org.geotools.api.style.Displacement;
+import org.geotools.api.style.FeatureTypeConstraint;
+import org.geotools.api.style.FeatureTypeStyle;
+import org.geotools.api.style.Fill;
+import org.geotools.api.style.Graphic;
+import org.geotools.api.style.GraphicalSymbol;
+import org.geotools.api.style.NamedLayer;
+import org.geotools.api.style.PointSymbolizer;
+import org.geotools.api.style.Rule;
+import org.geotools.api.style.Stroke;
+import org.geotools.api.style.Style;
+import org.geotools.api.style.StyleFactory;
+import org.geotools.api.style.StyledLayerDescriptor;
+import org.geotools.api.style.UserLayer;
+import org.geotools.data.DefaultTransaction;
+import org.geotools.data.collection.ListFeatureCollection;
+import org.geotools.data.shapefile.ShapefileDataStore;
+import org.geotools.data.shapefile.ShapefileDataStoreFactory;
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.geometry.jts.JTS;
+import org.geotools.referencing.CRS;
+import org.geotools.referencing.crs.DefaultGeographicCRS;
+import org.geotools.styling.css.CssParser;
+import org.geotools.styling.css.CssTranslator;
+import org.geotools.styling.css.Stylesheet;
+import org.geotools.xml.styling.SLDTransformer;
+import org.locationtech.jts.algorithm.hull.ConcaveHull;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.Point;
+import org.locationtech.jts.geom.Polygon;
+import org.locationtech.jts.geom.util.GeometryFixer;
+import org.locationtech.jts.operation.polygonize.Polygonizer;
+
+import si.uom.SI;
+import tech.units.indriya.quantity.Quantities;
+
+/** Utilities around geographical format, mostly wrapping GeoTools patterns. */
+public class GeoUtils {
+ public final static String EPSG_4326 = "EPSG:4326";
+
+ /** In square meters. */
+ public static Quantity<Area> calcArea(SimpleFeature feature) {
+ try {
+ Polygon polygon = (Polygon) feature.getDefaultGeometry();
+ Point centroid = polygon.getCentroid();
+// CoordinateReferenceSystem crs = feature.getDefaultGeometryProperty().getType()
+// .getCoordinateReferenceSystem();
+ // TODO convert the centroid
+// if (!crs.getName().equals(DefaultGeographicCRS.WGS84.getName()))
+// throw new IllegalArgumentException("Only WGS84 CRS is currently supported");
+
+ // create automatic CRS for optimal computation
+ String code = "AUTO:42001," + centroid.getX() + "," + centroid.getY();
+ CoordinateReferenceSystem auto = CRS.decode(code);
+
+ MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto);
+
+ Polygon projed = (Polygon) JTS.transform(polygon, transform);
+ return Quantities.getQuantity(projed.getArea(), SI.SQUARE_METRE);
+ } catch (MismatchedDimensionException | FactoryException | TransformException e) {
+ throw new IllegalStateException("Cannot calculate area of feature", e);
+ }
+ }
+
+ /** In square meters. The {@link Polygon} must use WGS84 coordinates. */
+ public static Quantity<Area> calcArea(Polygon polygon) {
+ assert polygon.getSRID() == 0 || polygon.getSRID() == 4326;
+ return calcArea(polygon, DefaultGeographicCRS.WGS84, polygon.getCentroid());
+ }
+
+ public static Quantity<Area> calcArea(Polygon polygon, CoordinateReferenceSystem crs, Point wgs84centroid) {
+ try {
+ // create automatic CRS for optimal computation
+ String code = "AUTO:42001," + wgs84centroid.getX() + "," + wgs84centroid.getY();
+ CoordinateReferenceSystem auto = CRS.decode(code);
+
+ MathTransform transform = CRS.findMathTransform(crs, auto);
+
+ Polygon projed = (Polygon) JTS.transform(polygon, transform);
+ return Quantities.getQuantity(projed.getArea(), SI.SQUARE_METRE);
+ } catch (MismatchedDimensionException | FactoryException | TransformException e) {
+ throw new IllegalStateException("Cannot calculate area of feature", e);
+ }
+ }
+
+ public static void exportToSvg(Geometry[] geometries, Writer out, int width, int height) {
+ try {
+ double minY = Double.POSITIVE_INFINITY;
+ double maxY = Double.NEGATIVE_INFINITY;
+ double minX = Double.POSITIVE_INFINITY;
+ double maxX = Double.NEGATIVE_INFINITY;
+ List<String> shapes = new ArrayList<>();
+ for (Geometry geometry : geometries) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("<polyline style=\"stroke-width:1;stroke:#000000;fill:none;\" points=\"");
+
+ if (geometry instanceof Polygon p) {
+ Point centroid = p.getCentroid();
+ String code = "AUTO:42001," + centroid.getX() + "," + centroid.getY();
+ CoordinateReferenceSystem auto = CRS.decode(code);
+
+ MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto);
+
+ Polygon projed = (Polygon) JTS.transform(p, transform);
+
+ // EPSG4326 are in lat/lon order, so we invert coordinates
+ for (Coordinate coord : projed.getCoordinates()) {
+ double x = coord.y;
+ if (x < minX)
+ minX = x;
+ if (x > maxX)
+ maxX = x;
+ double y = -coord.x;
+ if (y < minY)
+ minY = y;
+ if (y > maxY)
+ maxY = y;
+ sb.append(x + "," + y + " ");
+ }
+ sb.append("\">");
+ sb.append("</polyline>\n");
+ shapes.add(sb.toString());
+ } else {
+ throw new IllegalArgumentException("Unsuppported geometry type " + geometry.getClass().getName());
+ }
+ }
+ double viewportHeight = maxY - minY;
+ double viewportWidth = maxX - minX;
+ out.write("<svg xmlns=\"http://www.w3.org/2000/svg\"\n");
+ out.write(" width=\"" + width + "\"\n");
+ out.write(" height=\"" + height + "\"\n");
+ out.write(" viewBox=\"" + minX + " " + minY + " " + viewportWidth + " " + viewportHeight + "\"\n");
+ out.write(" preserveAspectRatio=\"xMidYMid meet\"\n");
+ out.write(">\n");
+ for (String shape : shapes) {
+ out.write(shape);
+ out.write("\n");
+ }
+ out.write("</svg>");
+ } catch (IOException | FactoryException | MismatchedDimensionException | TransformException e) {
+ throw new RuntimeException("Cannot export to SVG", e);
+ }
+ }
+
+ /** Write a list of simple features to a shapefile. */
+ public static void saveFeaturesAsShapefile(SimpleFeatureType featureType, List<SimpleFeature> features,
+ Path shpFile) {
+ try {
+ ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
+
+ Map<String, Serializable> params = new HashMap<>();
+ params.put("url", shpFile.toUri().toURL());
+
+ params.put("create spatial index", Boolean.TRUE);
+
+ ShapefileDataStore newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
+ newDataStore.createSchema(featureType);
+
+ String typeName = newDataStore.getTypeNames()[0];
+ SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName);
+ if (featureSource instanceof SimpleFeatureStore) {
+ SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
+ SimpleFeatureCollection collection = new ListFeatureCollection(featureType, features);
+
+ try (Transaction transaction = new DefaultTransaction("create")) {
+ try {
+ featureStore.setTransaction(transaction);
+ featureStore.addFeatures(collection);
+ transaction.commit();
+ } catch (Exception problem) {
+ transaction.rollback();
+ throw new RuntimeException("Cannot write shapefile " + shpFile, problem);
+ }
+ }
+ } else {
+ throw new IllegalArgumentException(typeName + " does not support read/write access");
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("Cannot write shapefile " + shpFile, e);
+ }
+ }
+
+ /*
+ * STYLING
+ */
+
+ public static Style createStyleFromCss(String css) {
+ Stylesheet ss = CssParser.parse(css);
+ CssTranslator translator = new CssTranslator();
+ Style style = translator.translate(ss);
+
+// try {
+// SLDTransformer styleTransform = new SLDTransformer();
+// String xml = styleTransform.transform(style);
+// System.out.println(xml);
+// } catch (TransformerException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+// }
+
+ return (Style) style;
+ }
+
+ public static String createSldFromCss(String name, String title, String css) {
+ StyledLayerDescriptor sld = GeoTools.STYLE_FACTORY.createStyledLayerDescriptor();
+ sld.setName(name);
+ sld.setTitle(title);
+
+ NamedLayer layer = GeoTools.STYLE_FACTORY.createNamedLayer();
+ layer.setName(name);
+
+ Style style = createStyleFromCss(css);
+ layer.styles().add(style);
+
+ sld.layers().add(layer);
+ return sldToXml(sld);
+ }
+
+ public static String sldToXml(StyledLayerDescriptor sld) {
+ try {
+ SLDTransformer styleTransform = new SLDTransformer();
+ String xml = styleTransform.transform(sld);
+// System.out.println(xml);
+ return xml;
+ } catch (TransformerException e) {
+ throw new IllegalStateException("Cannot write SLD as XML", e);
+ }
+ }
+
+ public static void main(String... args) {
+ String css = """
+ * {
+ mark: symbol(circle);
+ mark-size: 6px;
+ }
+
+ :mark {
+ fill: red;
+ }
+
+ """;
+ createSldFromCss("test", "Test", css);
+ }
+
+ public static String createTestSLD() {
+
+ StyleFactory sf = CommonFactoryFinder.getStyleFactory();
+ FilterFactory ff = CommonFactoryFinder.getFilterFactory();
+
+ StyledLayerDescriptor sld = sf.createStyledLayerDescriptor();
+ sld.setName("sld");
+ sld.setTitle("Example");
+ sld.setAbstract("Example Style Layer Descriptor");
+
+ UserLayer layer = sf.createUserLayer();
+ layer.setName("layer");
+
+ //
+ // define constraint limited what features the sld applies to
+ FeatureTypeConstraint constraint = sf.createFeatureTypeConstraint("Feature", Filter.INCLUDE);
+
+ layer.layerFeatureConstraints().add(constraint);
+
+ //
+ // create a "user defined" style
+ Style style = sf.createStyle();
+ style.setName("style");
+ style.getDescription().setTitle("User Style");
+ style.getDescription().setAbstract("Definition of Style");
+
+ //
+ // define feature type styles used to actually define how features are rendered
+ FeatureTypeStyle featureTypeStyle = sf.createFeatureTypeStyle();
+
+ // RULE 1
+ // first rule to draw cities
+ Rule rule1 = sf.createRule();
+ rule1.setName("rule1");
+ rule1.getDescription().setTitle("City");
+ rule1.getDescription().setAbstract("Rule for drawing cities");
+// rule1.setFilter(ff.less(ff.property("POPULATION"), ff.literal(50000)));
+
+ //
+ // create the graphical mark used to represent a city
+ Stroke stroke = sf.stroke(ff.literal("#000000"), null, null, null, null, null, null);
+ Fill fill = sf.fill(null, ff.literal(java.awt.Color.BLUE), ff.literal(1.0));
+
+// // OnLineResource implemented by gt-metadata - so no factory!
+// OnLineResourceImpl svg = new OnLineResourceImpl(new URI("file:city.svg"));
+// svg.freeze(); // freeze to prevent modification at runtime
+//
+// OnLineResourceImpl png = new OnLineResourceImpl(new URI("file:city.png"));
+// png.freeze(); // freeze to prevent modification at runtime
+
+ //
+ // List of symbols is considered in order with the rendering engine choosing
+ // the first one it can handle. Allowing for svg, png, mark order
+ List<GraphicalSymbol> symbols = new ArrayList<>();
+// symbols.add(sf.externalGraphic(svg, "svg", null)); // svg preferred
+// symbols.add(sf.externalGraphic(png, "png", null)); // png preferred
+ symbols.add(sf.mark(ff.literal("circle"), fill, stroke)); // simple circle backup plan
+
+ Expression opacity = null; // use default
+ Expression size = ff.literal(10);
+ Expression rotation = null; // use default
+ AnchorPoint anchor = null; // use default
+ Displacement displacement = null; // use default
+
+ // define a point symbolizer of a small circle
+ Graphic city = sf.graphic(symbols, opacity, size, rotation, anchor, displacement);
+ PointSymbolizer pointSymbolizer = sf.pointSymbolizer("point", ff.property("the_geom"), null, null, city);
+
+ rule1.symbolizers().add(pointSymbolizer);
+
+ featureTypeStyle.rules().add(rule1);
+
+ //
+ // RULE 2 Default
+
+// List<GraphicalSymbol> dotSymbols = new ArrayList<>();
+// dotSymbols.add(sf.mark(ff.literal("circle"), null, null));
+// Graphic dotGraphic = sf.graphic(dotSymbols, null, ff.literal(3), null, null, null);
+// PointSymbolizer dotSymbolizer = sf.pointSymbolizer("dot", ff.property("the_geom"), null, null, dotGraphic);
+// List<org.opengis.style.Symbolizer> symbolizers = new ArrayList<>();
+// symbolizers.add(dotSymbolizer);
+// Filter other = null; // null will mark this rule as "other" accepting all remaining features
+// Rule rule2 = sf.rule("default", null, null, Double.MIN_VALUE, Double.MAX_VALUE, symbolizers, other);
+// featureTypeStyle.rules().add(rule2);
+
+ style.featureTypeStyles().add(featureTypeStyle);
+
+ layer.userStyles().add(style);
+
+ sld.layers().add(layer);
+
+ try {
+ SLDTransformer styleTransform = new SLDTransformer();
+ String xml = styleTransform.transform(sld);
+ System.out.println(xml);
+ return xml;
+ } catch (TransformerException e) {
+ throw new IllegalStateException(e);
+ }
+
+ }
+
+ public static long getScaleFromResolution(long resolution) {
+ // see
+ // https://gis.stackexchange.com/questions/242424/how-to-get-map-units-to-find-current-scale-in-openlayers
+ final double INCHES_PER_UNIT = 39.37;// m
+ // final double INCHES_PER_UNIT = 4374754;// dd
+ final long DOTS_PER_INCH = 72;
+ return Math.round(INCHES_PER_UNIT * DOTS_PER_INCH * resolution);
+ }
+
+ /*
+ * GEOMETRY
+ */
+ /**
+ * Ensure that a {@link Polygon} is valid and simple by removing artefacts
+ * (typically coming from GPS).
+ *
+ * @return a simple and valid polygon, or null if the ignoredArea ratio is above
+ * the provided threshold.
+ */
+ public static Polygon cleanPolygon(Polygon polygon, double ignoredAreaRatio) {
+ Polygonizer polygonizer = new Polygonizer(true);
+ Geometry fixed = GeometryFixer.fix(polygon, false);
+ polygonizer.add(fixed);
+ @SuppressWarnings("unchecked")
+ List<Polygon> polygons = new ArrayList<>(polygonizer.getPolygons());
+
+ if (polygons.size() == 0) {
+ throw new IllegalStateException("Polygonizer failed to extract any polygon");
+ }
+
+ Polygon best;
+ if (polygons.size() == 1) {
+ best = polygons.get(0);
+ } else {
+ double totalArea = fixed.getArea();
+ best = polygons.get(0);
+ double bestArea = best.getArea();
+ for (int i = 1; i < polygons.size(); i++) {
+ Polygon p = polygons.get(i);
+ double a = p.getArea();
+ if (a > bestArea) {
+ best = p;
+ bestArea = a;
+ } else {
+ // double ratio = a / totalArea;
+ }
+ }
+ double ignoredRatio = (totalArea - bestArea) / totalArea;
+ if (ignoredRatio > ignoredAreaRatio)
+ return null;
+
+ if (!best.isValid() || !best.isSimple()) {
+ throw new IllegalStateException("The polygon is not simple and/or valid after cleaning");
+ }
+ }
+ // while we are here, we make sure that the geometry will be normalised
+ best.normalize();
+ return best;
+ }
+
+ /**
+ * The smallest polygon without holes containing all the points in this
+ * geometry.
+ */
+ public static Polygon concaveHull(Geometry geom, double lengthRatio) {
+ Objects.requireNonNull(geom);
+ if (geom.getNumPoints() < 3)
+ throw new IllegalArgumentException("At least 3 points are reuired to compute the concave hull and geometry "
+ + geom.getClass() + " contains only " + geom.getNumPoints());
+ Geometry hull = ConcaveHull.concaveHullByLengthRatio(geom, lengthRatio, false);
+ if (hull instanceof Polygon polygon)
+ return polygon;
+ else
+ throw new IllegalStateException("Hull is not a polygon but a " + hull.getClass());
+ }
+
+ /** Singleton. */
+ private GeoUtils() {
+ }
+}
--- /dev/null
+package org.argeo.app.geo;
+
+import org.argeo.api.acr.QNamed;
+
+public enum GmlAttr implements QNamed {
+ uom
+ //
+ ;
+
+ public final static String UOM_SQUARE_METERS = "m2";
+
+ @Override
+ public String getNamespace() {
+ return "http://www.opengis.net/gml/3.2";
+ }
+
+ @Override
+ public String getDefaultPrefix() {
+ return "gml";
+ }
+
+}
--- /dev/null
+package org.argeo.app.geo;
+
+import org.argeo.api.acr.QNamed;
+
+public enum GmlType implements QNamed {
+ measure
+ //
+ ;
+
+ @Override
+ public String getNamespace() {
+ return "http://www.opengis.net/gml/3.2";
+ }
+
+ @Override
+ public String getDefaultPrefix() {
+ return "gml";
+ }
+
+}
--- /dev/null
+package org.argeo.app.geo;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.StringTokenizer;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.geotools.api.feature.simple.SimpleFeature;
+import org.geotools.api.feature.simple.SimpleFeatureType;
+import org.geotools.data.DataUtilities;
+import org.geotools.feature.SchemaException;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.GeometryFactory;
+import org.locationtech.jts.geom.LineString;
+import org.locationtech.jts.geom.MultiPoint;
+import org.locationtech.jts.geom.Polygon;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/** Utilities around the GPX format. */
+public class GpxUtils {
+ /** GPX as a LineString in WGS84 (feature type with only the_geom). */
+ public static final SimpleFeatureType LINESTRING_FEATURE_TYPE;
+ /** GPX as a Polygon in WGS84 (feature type with only the_geom). */
+ public static final SimpleFeatureType POLYGON_FEATURE_TYPE;
+
+ static {
+ try {
+ LINESTRING_FEATURE_TYPE = DataUtilities.createType("Area", "the_geom:LineString:srid=4326");
+ POLYGON_FEATURE_TYPE = DataUtilities.createType("Area", "the_geom:Polygon:srid=4326");
+ } catch (SchemaException e) {
+ throw new RuntimeException("Cannot create GPX Feature type", e);
+ }
+ }
+
+ /**
+ * Converts a GPX track to either a {@link Geometry} with WGS84 coordinates
+ * ({@link LineString} or {@link Polygon}) or a {@link SimpleFeature} (with
+ * {@link #LINESTRING_FEATURE_TYPE}).
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T parseGpxTrackTo(InputStream in, Class<T> clss) throws IOException {
+ GeometryFactory geometryFactory = JTS.GEOMETRY_FACTORY_WGS84;
+ List<Coordinate> coordinates = new ArrayList<>();
+ try {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ SAXParser saxParser = factory.newSAXParser();
+
+ saxParser.parse(in, new DefaultHandler() {
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes)
+ throws SAXException {
+ if ("trkpt".equals(qName)) {
+ Double latitude = Double.parseDouble(attributes.getValue("lat"));
+ Double longitude = Double.parseDouble(attributes.getValue("lon"));
+ // TODO elevation in 3D context
+ Coordinate coordinate = new Coordinate(latitude, longitude);
+ coordinates.add(coordinate);
+ }
+ }
+
+ });
+ } catch (ParserConfigurationException | SAXException e) {
+ throw new RuntimeException("Cannot convert GPX", e);
+ }
+
+ if (LineString.class.isAssignableFrom(clss)) {
+ LineString lineString = geometryFactory
+ .createLineString(coordinates.toArray(new Coordinate[coordinates.size()]));
+ return (T) lineString;
+ } else if (MultiPoint.class.isAssignableFrom(clss)) {
+ MultiPoint multiPoint = geometryFactory
+ .createMultiPointFromCoords(coordinates.toArray(new Coordinate[coordinates.size()]));
+ // multiPoint.normalize();
+ return (T) multiPoint;
+ } else if (Polygon.class.isAssignableFrom(clss)) {
+ Coordinate first = coordinates.get(0);
+ Coordinate last = coordinates.get(coordinates.size() - 1);
+ if (!(first.getX() == last.getX() && first.getY() == last.getY())) {
+ // close the line string
+ coordinates.add(first);
+ }
+ Polygon polygon = geometryFactory.createPolygon(coordinates.toArray(new Coordinate[coordinates.size()]));
+ return (T) polygon;
+ } else if (SimpleFeature.class.isAssignableFrom(clss)) {
+ SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(LINESTRING_FEATURE_TYPE);
+ LineString lineString = geometryFactory
+ .createLineString(coordinates.toArray(new Coordinate[coordinates.size()]));
+ featureBuilder.add(lineString);
+ SimpleFeature area = featureBuilder.buildFeature(null);
+ return (T) area;
+ } else {
+ throw new IllegalArgumentException("Unsupported format " + clss);
+ }
+ }
+
+ /** @deprecated Use {@link #parseGpxTrackTo(InputStream, Class)} instead. */
+ @Deprecated
+ public static SimpleFeature parseGpxToPolygon(InputStream in) throws IOException {
+ SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(POLYGON_FEATURE_TYPE);
+ Polygon polygon = parseGpxTrackTo(in, Polygon.class);
+ featureBuilder.add(polygon);
+ SimpleFeature area = featureBuilder.buildFeature(null);
+ return area;
+ }
+
+ /** Write ODK GeoShape as a GPX file. */
+ public static void writeGeoShapeAsGpx(String geoShape, OutputStream out) throws IOException {
+ Objects.requireNonNull(geoShape);
+ Writer writer = new OutputStreamWriter(out, StandardCharsets.UTF_8);
+ writer.append("<gpx><trk><trkseg>");
+ StringTokenizer stSeg = new StringTokenizer(geoShape.trim(), ";");
+ while (stSeg.hasMoreTokens()) {
+ StringTokenizer stPt = new StringTokenizer(stSeg.nextToken().trim(), " ");
+ String lat = stPt.nextToken();
+ String lng = stPt.nextToken();
+ String alt = stPt.nextToken();
+ // String precision = stPt.nextToken();
+ writer.append("<trkpt");
+ writer.append(" lat=\"").append(lat).append('\"');
+ writer.append(" lon=\"").append(lng).append('\"');
+ if (!alt.equals("0.0")) {
+ writer.append('>');
+ writer.append("<ele>").append(alt).append("</ele>");
+ writer.append("</trkpt>");
+ } else {
+ writer.append("/>");
+ }
+ }
+ writer.append("</trkseg></trk></gpx>");
+ writer.flush();
+ }
+
+ /** Singleton. */
+ private GpxUtils() {
+ }
+}
--- /dev/null
+package org.argeo.app.geo;
+
+import org.argeo.api.cms.CmsLog;
+import org.locationtech.jts.geom.GeometryFactory;
+import org.locationtech.jts.geom.PrecisionModel;
+
+/**
+ * Factories initialisation and workarounds for the JTS library. The idea is to
+ * code defensively around factory initialisation, API changes, and issues
+ * related to running in an OSGi environment. Rather see {@link GeoUtils} for
+ * functional static utilities.
+ */
+public class JTS {
+ private final static CmsLog log = CmsLog.getLog(JTS.class);
+
+ public final static int WGS84_SRID = 4326;
+
+ /** A geometry factory with no SRID specified */
+ public final static GeometryFactory GEOMETRY_FACTORY;
+ /** A geometry factory with SRID 4326 (WGS84 in the EPSG database) */
+ public final static GeometryFactory GEOMETRY_FACTORY_WGS84;
+
+ static {
+ try {
+ GEOMETRY_FACTORY = new GeometryFactory();
+ GEOMETRY_FACTORY_WGS84 = new GeometryFactory(new PrecisionModel(), WGS84_SRID);
+ } catch (RuntimeException e) {
+ log.error("Basic JTS initialisation failed, geographical utilities are probably not available", e);
+ throw e;
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.app.geo.acr;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.argeo.api.acr.Content;
+import org.argeo.api.acr.ContentName;
+import org.argeo.api.acr.DName;
+import org.argeo.api.acr.QNamed;
+import org.argeo.app.api.EntityName;
+import org.argeo.app.api.EntityType;
+import org.argeo.app.api.WGS84PosName;
+import org.argeo.app.geo.GeoJson;
+import org.argeo.app.geo.JTS;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.Envelope;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.GeometryCollection;
+import org.locationtech.jts.geom.Point;
+
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonReader;
+import jakarta.json.stream.JsonGenerator;
+
+/** Utilities around entity types related to geography. */
+public class GeoEntityUtils {
+ public static final String _GEOM_JSON = ".geom.json";
+
+ public static void putGeometry(Content c, QNamed name, Geometry geometry) {
+ putGeometry(c, name.qName(), geometry);
+ }
+
+ public static void putGeometry(Content c, QName name, Geometry geometry) {
+ QName jsonFileName = getJsonFileName(name);
+ Content geom = c.soleChild(jsonFileName).orElseGet(
+ () -> c.add(jsonFileName, Collections.singletonMap(DName.getcontenttype.qName(), "application/json")));
+ try (OutputStream out = geom.open(OutputStream.class)) {
+ JsonGenerator g = Json.createGenerator(out);
+ g.writeStartObject();
+ GeoJson.writeGeometry(g, geometry);
+ g.writeEnd();
+ g.close();
+ } catch (IOException e) {
+ throw new UncheckedIOException("Cannot add geometry " + name + " to " + c, e);
+ }
+
+// try (BufferedReader in = new BufferedReader(
+// new InputStreamReader(geom.open(InputStream.class), StandardCharsets.UTF_8))) {
+// System.out.println(in.readLine());
+// } catch (IOException e) {
+// throw new UncheckedIOException("Cannot parse " + c, e);
+// }
+ updateBoundingBox(c);
+ }
+
+ public static boolean hasGeometry(Content c, QNamed name) {
+ return hasGeometry(c, name.qName());
+ }
+
+ public static boolean hasGeometry(Content c, QName name) {
+ QName jsonFileName = getJsonFileName(name);
+ return c.hasChild(jsonFileName);
+ }
+
+ public static <T extends Geometry> T getGeometry(Content c, QNamed name, Class<T> clss) {
+ return getGeometry(c, name.qName(), clss);
+ }
+
+ public static <T extends Geometry> T getGeometry(Content c, QName name, Class<T> clss) {
+ QName jsonFileName = getJsonFileName(name);
+ Content geom = c.soleChild(jsonFileName).orElse(null);
+ if (geom == null)
+ return null;
+ try (Reader in = new InputStreamReader(geom.open(InputStream.class), StandardCharsets.UTF_8)) {
+ JsonReader jsonReader = Json.createReader(in);
+ JsonObject jsonObject = jsonReader.readObject();
+ T readGeom = GeoJson.readGeometry(jsonObject, clss);
+ return readGeom;
+ } catch (IOException e) {
+ throw new UncheckedIOException("Cannot parse " + c, e);
+ }
+ }
+
+ private static QName getJsonFileName(QName name) {
+ QName jsonFileName = new ContentName(name.getNamespaceURI(), name.getLocalPart() + _GEOM_JSON);
+ return jsonFileName;
+ }
+
+ public static Point toPoint(Content c) {
+ if (c.containsKey(WGS84PosName.lon) && c.containsKey(WGS84PosName.lat)) {
+ Double lat = c.get(WGS84PosName.lat, Double.class).orElseThrow();
+ Double lon = c.get(WGS84PosName.lon, Double.class).orElseThrow();
+ return JTS.GEOMETRY_FACTORY_WGS84.createPoint(new Coordinate(lat, lon));
+// Double alt = c.get(WGS84PosName.alt, Double.class).orElse(null);
+// return JTS.GEOMETRY_FACTORY_WGS84
+// .createPoint(alt != null ? new Coordinate(lat, lon, alt) : new Coordinate(lat, lon));
+ }
+ return null;
+ }
+
+ public static GeometryCollection getGeometries(Content entity) {
+ List<Geometry> geoms = new ArrayList<>();
+ Point geoPoint = toPoint(entity);
+ if (geoPoint != null)
+ geoms.add(geoPoint);
+
+ Geometry place = getGeometry(entity, EntityName.place.qName(), Geometry.class);
+ if (place != null)
+ geoms.add(place);
+
+ if (geoms.isEmpty())
+ return null;
+ GeometryCollection geometryCollection = JTS.GEOMETRY_FACTORY_WGS84
+ .createGeometryCollection(geoms.toArray(new Geometry[geoms.size()]));
+ return geometryCollection;
+ }
+
+ public static void updateBoundingBox(Content entity) {
+ GeometryCollection geometryCollection = getGeometries(entity);
+ if (geometryCollection == null)
+ return;
+ entity.addContentClasses(EntityType.geobounded.qName());
+
+ Envelope bbox = geometryCollection.getEnvelopeInternal();
+ entity.put(EntityName.minLat, bbox.getMinX());
+ entity.put(EntityName.minLon, bbox.getMinY());
+ entity.put(EntityName.maxLat, bbox.getMaxX());
+ entity.put(EntityName.maxLon, bbox.getMaxY());
+ }
+
+ public static void updateBoundingBox(Content entity, QName prop) {
+ Geometry geom = getGeometry(entity, prop, Geometry.class);
+ if (geom == null)
+ return;
+ entity.addContentClasses(EntityType.geobounded.qName());
+
+ Envelope bbox = geom.getEnvelopeInternal();
+ entity.put(EntityName.minLat, bbox.getMinX());
+ entity.put(EntityName.minLon, bbox.getMinY());
+ entity.put(EntityName.maxLat, bbox.getMaxX());
+ entity.put(EntityName.maxLon, bbox.getMaxY());
+ }
+
+ /** singleton */
+ private GeoEntityUtils() {
+ }
+
+}
--- /dev/null
+package org.argeo.app.geo.geonames;
+
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+/** A Geonames administrative subdivision. */
+public class GeonamesAdm {
+ private final Long geonameId;
+ private final String countryCode;
+ private final String adminCode1;
+ private final String admLevel;
+ private final Integer level;
+ private final String name;
+ private final String asciiName;
+ private final List<String> alternateNames;
+ private final Double lat;
+ private final Double lng;
+ private final LocalDate lastUpdated;
+ private final ZoneId timeZone;
+
+ private final Long[] upperLevelIds = new Long[5];
+ private final List<GeonamesAdm> upperLevels = new ArrayList<>();
+
+ private List<String> row;
+
+ /** Initialise from a row in the main Geonames table. */
+ public GeonamesAdm(List<String> row) {
+ geonameId = Long.parseLong(row.get(0));
+ admLevel = row.get(7);
+ countryCode = row.get(8);
+ adminCode1 = row.get(10);
+ if (admLevel.startsWith("ADM")) {
+ if (admLevel.endsWith("H"))
+ level = Integer.parseInt(admLevel.substring(3, admLevel.length() - 1));
+ else
+ level = Integer.parseInt(admLevel.substring(3));
+ } else if (admLevel.equals("PCLI")) {
+ level = 0;
+ } else {
+ throw new IllegalArgumentException("Unsupported admin level " + admLevel);
+ }
+ name = row.get(1);
+ asciiName = row.get(2);
+ alternateNames = Arrays.asList(row.get(3).split(","));
+ lat = Double.parseDouble(row.get(4));
+ lng = Double.parseDouble(row.get(5));
+ lastUpdated = LocalDate.parse(row.get(18));
+ timeZone = ZoneId.of(row.get(17));
+ // upper levels
+ if (row.get(11) != null && !row.get(11).trim().equals(""))
+ upperLevelIds[2] = Long.parseLong(row.get(11));
+ if (row.get(12) != null && !row.get(12).trim().equals(""))
+ upperLevelIds[3] = Long.parseLong(row.get(12));
+ if (row.get(13) != null && !row.get(13).trim().equals(""))
+ upperLevelIds[4] = Long.parseLong(row.get(13));
+ this.row = row;
+ }
+
+ public void mapUpperLevels(Map<Long, GeonamesAdm> index) {
+ for (int i = 0; i < level; i++) {
+ Long geonameId = upperLevelIds[i];
+ upperLevels.add(i, index.get(geonameId));
+ }
+ }
+
+ public Long getGeonameId() {
+ return geonameId;
+ }
+
+ public Integer getLevel() {
+ return level;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getName(Function<String, String> transform) {
+ if (transform != null)
+ return transform.apply(name);
+ else
+ return name;
+
+ }
+
+ public String getAsciiName() {
+ return asciiName;
+ }
+
+ public List<String> getAlternateNames() {
+ return alternateNames;
+ }
+
+ public Double getLat() {
+ return lat;
+ }
+
+ public Double getLng() {
+ return lng;
+ }
+
+ public String getCountryCode() {
+ return countryCode;
+ }
+
+ public String getAdmLevel() {
+ return admLevel;
+ }
+
+ public List<String> getRow() {
+ return row;
+ }
+
+ public LocalDate getLastUpdated() {
+ return lastUpdated;
+ }
+
+ public ZoneId getTimeZone() {
+ return timeZone;
+ }
+
+ public String getAdminCode1() {
+ return adminCode1;
+ }
+
+ public Long[] getUpperLevelIds() {
+ return upperLevelIds;
+ }
+
+ public List<GeonamesAdm> getUpperLevels() {
+ return upperLevels;
+ }
+
+ @Override
+ public int hashCode() {
+ return geonameId.intValue();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof GeonamesAdm))
+ return false;
+ GeonamesAdm other = (GeonamesAdm) obj;
+ return geonameId.equals(other.geonameId);
+ }
+
+ @Override
+ public String toString() {
+ return name + " (ADM" + level + " " + geonameId + ")";
+ }
+
+}
--- /dev/null
+package org.argeo.app.geo.geonames;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.argeo.cms.util.CsvParser;
+import org.argeo.cms.util.CsvWriter;
+
+/** Import GeoNames administrative division from the main table. */
+public class ImportGeonamesAdmin {
+ // private Log log = LogFactory.getLog(ImportGeonamesAdmin.class);
+ private Map<Long, GeonamesAdm> geonamesAdms = new HashMap<>();
+
+ /** Loads the data. */
+ public void parse(InputStream in) {
+ Map<String, Long> countryGeonameIds = new HashMap<>();
+ Map<String, Long> admin1GeonameIds = new HashMap<>();
+ CsvParser csvParser = new CsvParser() {
+
+ @Override
+ protected void processLine(Integer lineNumber, List<String> header, List<String> tokens) {
+ if (!"A".equals(tokens.get(6)))
+ return;
+ GeonamesAdm geonamesAdm = new GeonamesAdm(tokens);
+ geonamesAdms.put(geonamesAdm.getGeonameId(), geonamesAdm);
+ if (geonamesAdm.getAdmLevel().equals("PCLI"))
+ countryGeonameIds.put(geonamesAdm.getCountryCode(), geonamesAdm.getGeonameId());
+ if (geonamesAdm.getAdmLevel().equals("ADM1"))
+ admin1GeonameIds.put(geonamesAdm.getAdminCode1(), geonamesAdm.getGeonameId());
+ }
+ };
+ csvParser.setSeparator('\t');
+ csvParser.setNoHeader(true);
+ csvParser.parse(in, StandardCharsets.UTF_8);
+
+ // fill upper levels
+ for (GeonamesAdm adm : geonamesAdms.values()) {
+ adm.getUpperLevelIds()[0] = countryGeonameIds.get(adm.getCountryCode());
+ if (adm.getLevel() > 0)
+ adm.getUpperLevelIds()[1] = admin1GeonameIds.get(adm.getAdminCode1());
+ adm.mapUpperLevels(geonamesAdms);
+ }
+
+ }
+
+ public Map<Long, GeonamesAdm> getGeonamesAdms() {
+ return geonamesAdms;
+ }
+
+ /**
+ * Copies only the Geonames of feature class 'A' (administrative subdivisions).
+ */
+ public static void filterGeonamesAdm(InputStream in, OutputStream out) {
+ CsvWriter csvWriter = new CsvWriter(out, StandardCharsets.UTF_8);
+ csvWriter.setSeparator('\t');
+ CsvParser csvParser = new CsvParser() {
+
+ @Override
+ protected void processLine(Integer lineNumber, List<String> header, List<String> tokens) {
+ if (tokens.size() < 7 || !"A".equals(tokens.get(6)))
+ return;
+ csvWriter.writeLine(tokens);
+ }
+ };
+ csvParser.setSeparator('\t');
+ csvParser.setNoHeader(true);
+ csvParser.parse(in, StandardCharsets.UTF_8);
+ }
+
+ public static void main(String[] args) throws IOException {
+// String country = "allCountries";
+ String country = "CI";
+// try (InputStream in = Files
+// .newInputStream(Paths.get(System.getProperty("user.home") + "/gis/data/geonames/" + country + ".txt"));
+// OutputStream out = Files.newOutputStream(
+// Paths.get(System.getProperty("user.home") + "/gis/data/geonames/" + country + "-adm.txt"))) {
+// ImportGeonamesAdmin.filterGeonamesAdm(in, out);
+// }
+ try (InputStream in = Files.newInputStream(
+ Paths.get(System.getProperty("user.home") + "/gis/data/geonames/" + country + "-adm.txt"))) {
+ ImportGeonamesAdmin importGeonamesAdmin = new ImportGeonamesAdmin();
+ importGeonamesAdmin.parse(in);
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.app.geo.http;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UncheckedIOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import javax.xml.namespace.QName;
+
+import org.argeo.api.acr.Content;
+import org.argeo.api.acr.ContentSession;
+import org.argeo.api.acr.NamespaceUtils;
+import org.argeo.api.acr.ldap.LdapAttr;
+import org.argeo.api.acr.search.AndFilter;
+import org.argeo.api.acr.spi.ProvidedRepository;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.app.api.EntityName;
+import org.argeo.app.api.EntityType;
+import org.argeo.app.api.WGS84PosName;
+import org.argeo.app.api.geo.FeatureAdapter;
+import org.argeo.app.api.geo.WfsKvp;
+import org.argeo.app.geo.CqlUtils;
+import org.argeo.app.geo.GeoJson;
+import org.argeo.app.geo.GeoUtils;
+import org.argeo.app.geo.GpxUtils;
+import org.argeo.app.geo.JTS;
+import org.argeo.app.geo.acr.GeoEntityUtils;
+import org.argeo.cms.acr.json.AcrJsonUtils;
+import org.argeo.cms.auth.RemoteAuthUtils;
+import org.argeo.cms.http.HttpHeader;
+import org.argeo.cms.http.RemoteAuthHttpExchange;
+import org.argeo.cms.http.server.HttpServerUtils;
+import org.argeo.cms.util.LangUtils;
+import org.geotools.api.feature.GeometryAttribute;
+import org.geotools.api.feature.simple.SimpleFeature;
+import org.geotools.api.feature.simple.SimpleFeatureType;
+import org.geotools.api.feature.type.AttributeDescriptor;
+import org.geotools.api.feature.type.Name;
+import org.geotools.api.referencing.FactoryException;
+import org.geotools.api.referencing.crs.CoordinateReferenceSystem;
+import org.geotools.api.referencing.operation.MathTransform;
+import org.geotools.api.referencing.operation.TransformException;
+import org.geotools.feature.DefaultFeatureCollection;
+import org.geotools.feature.NameImpl;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.referencing.CRS;
+import org.geotools.referencing.crs.DefaultGeographicCRS;
+import org.geotools.wfs.GML;
+import org.geotools.wfs.GML.Version;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.Envelope;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.Polygon;
+
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+
+import jakarta.json.Json;
+import jakarta.json.stream.JsonGenerator;
+
+/** A partially implemented WFS 2.0 server. */
+public class WfsHttpHandler implements HttpHandler {
+ private final static CmsLog log = CmsLog.getLog(WfsHttpHandler.class);
+ private ProvidedRepository contentRepository;
+
+ private final Map<QName, FeatureAdapter> featureAdapters = new HashMap<>();
+
+ @Override
+ public void handle(HttpExchange exchange) throws IOException {
+ ContentSession session = HttpServerUtils.getContentSession(contentRepository, exchange);
+
+ String path = HttpServerUtils.subPath(exchange);
+
+ // content path
+ final String pathToUse = path;
+ String fileName = null;
+ boolean zipped = false;
+// int lastSlash = path.lastIndexOf('/');
+// if (lastSlash > 0) {
+// fileName = path.substring(lastSlash + 1);
+// }
+// if (fileName != null) {
+// pathToUse = path.substring(0, lastSlash);
+// if (path.endsWith(".zip")) {
+// zipped = true;
+// }
+// } else {
+// pathToUse = path;
+// }
+
+ Map<String, List<String>> parameters = HttpServerUtils.parseParameters(exchange);
+
+ // PARAMETERS
+ String cql = getKvpParameter(parameters, WfsKvp.CQL_FILTER);
+ String typeNamesStr = getKvpParameter(parameters, WfsKvp.TYPE_NAMES);
+ String outputFormat = getKvpParameter(parameters, WfsKvp.OUTPUT_FORMAT);
+ if (outputFormat == null) {
+ outputFormat = "application/json";
+ }
+
+ // TODO deal with multiple
+ String formatOption = getKvpParameter(parameters, WfsKvp.FORMAT_OPTIONS);
+ if (formatOption != null) {
+ if (formatOption.startsWith(WfsKvp.FILENAME_))
+ fileName = formatOption.substring(WfsKvp.FILENAME_.length());
+ }
+ if (fileName != null && fileName.endsWith(".zip"))
+ zipped = true;
+
+ // bbox
+ String bboxStr = getKvpParameter(parameters, WfsKvp.BBOX);
+ if (log.isTraceEnabled())
+ log.trace(bboxStr);
+ final Envelope bbox;
+ if (bboxStr != null) {
+ String srs;
+ String[] arr = bboxStr.split(",");
+ // TODO check SRS and convert to WGS84
+ double minLat = Double.parseDouble(arr[0]);
+ double minLon = Double.parseDouble(arr[1]);
+ double maxLat = Double.parseDouble(arr[2]);
+ double maxLon = Double.parseDouble(arr[3]);
+ if (arr.length == 5) {
+ srs = arr[4];
+ } else {
+ srs = null;
+ }
+
+ if (srs != null && !srs.equals(GeoUtils.EPSG_4326)) {
+ try {
+ // TODO optimise
+ CoordinateReferenceSystem sourceCRS = CRS.decode(srs);
+ CoordinateReferenceSystem targetCRS = CRS.decode(GeoUtils.EPSG_4326);
+ MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
+ bbox = org.geotools.geometry.jts.JTS.transform(
+ new Envelope(new Coordinate(minLat, minLon), new Coordinate(maxLat, maxLon)), transform);
+ } catch (FactoryException | TransformException e) {
+ throw new IllegalArgumentException("Cannot convert bounding box", e);
+ // bbox = null;
+ }
+ } else {
+ bbox = new Envelope(new Coordinate(minLat, minLon), new Coordinate(maxLat, maxLon));
+ }
+ } else {
+ bbox = null;
+ }
+
+ // response headers
+ exchange.getResponseHeaders().set(HttpHeader.DATE.getHeaderName(), Long.toString(System.currentTimeMillis()));
+
+ if (fileName != null) {
+ exchange.getResponseHeaders().set(HttpHeader.CONTENT_DISPOSITION.getHeaderName(),
+ HttpHeader.ATTACHMENT + ";" + HttpHeader.FILENAME + "=\"" + fileName + "\"");
+
+ }
+
+ // content type
+ if (zipped) {
+ exchange.getResponseHeaders().set(HttpHeader.CONTENT_TYPE.getHeaderName(), "application/zip");
+
+ } else {
+ switch (outputFormat) {
+ case "application/json" -> {
+ exchange.getResponseHeaders().set(HttpHeader.CONTENT_TYPE.getHeaderName(), "application/json");
+ }
+ case "GML3" -> {
+// exchange.getResponseHeaders().set(HttpHeader.CONTENT_TYPE.getHeaderName(), "application/gml+xml");
+ exchange.getResponseHeaders().set(HttpHeader.CONTENT_TYPE.getHeaderName(), "application/xml");
+ }
+
+ default -> throw new IllegalArgumentException("Unexpected value: " + outputFormat);
+ }
+ }
+
+ List<QName> typeNames = new ArrayList<>();
+ if (typeNamesStr != null) {
+ String[] arr = typeNamesStr.split(",");
+ for (int i = 0; i < arr.length; i++) {
+ typeNames.add(NamespaceUtils.parsePrefixedName(arr[i]));
+ }
+ } else {
+ typeNames.add(EntityType.local.qName());
+ }
+
+ if (typeNames.size() > 1)
+ throw new UnsupportedOperationException("Only one type name is currently supported");
+
+ // QUERY
+ Stream<Content> res = session.search((search) -> {
+ if (cql != null) {
+ CqlUtils.filter(search.from(pathToUse), cql);
+ } else {
+ search.from(pathToUse);
+ }
+ for (QName typeName : typeNames) {
+ FeatureAdapter featureAdapter = featureAdapters.get(typeName);
+ if (featureAdapter == null)
+ throw new IllegalStateException("No feature adapter found for " + typeName);
+ // f.isContentClass(typeName);
+ RemoteAuthUtils.doAs(() -> {
+ featureAdapter.addConstraintsForFeature((AndFilter) search.getWhere(), typeName);
+ return null;
+ }, new RemoteAuthHttpExchange(exchange));
+ }
+
+ if (bbox != null) {
+ search.getWhere().any((or) -> {
+ // box overlap, see https://stackoverflow.com/questions/20925818/algorithm-to-check-if-two-boxes-overlap
+ // isOverlapping = (x1min < x2max AND x2min < x1max AND y1min < y2max AND y2min < y1max)
+ // x1 = entity, x2 = bbox
+ or.all((and) -> {
+ and.lte(EntityName.minLat, bbox.getMaxX());
+ and.gte(EntityName.maxLat, bbox.getMinX());
+ and.lte(EntityName.minLon, bbox.getMaxY());
+ and.gte(EntityName.maxLon, bbox.getMinY());
+ });
+ or.all((and) -> {
+ and.gte(WGS84PosName.lat, bbox.getMinX());
+ and.gte(WGS84PosName.lon, bbox.getMinY());
+ and.lte(WGS84PosName.lat, bbox.getMaxX());
+ and.lte(WGS84PosName.lon, bbox.getMaxY());
+ });
+ });
+ }
+ });
+
+ exchange.sendResponseHeaders(200, 0);
+
+ final int BUFFER_SIZE = 100 * 1024;
+ try (OutputStream out = zipped ? new ZipOutputStream(exchange.getResponseBody())
+ : new BufferedOutputStream(exchange.getResponseBody(), BUFFER_SIZE)) {
+ if (out instanceof ZipOutputStream zipOut) {
+ String unzippedFileName = fileName.substring(0, fileName.length() - ".zip".length());
+ zipOut.putNextEntry(new ZipEntry(unzippedFileName));
+ }
+
+ if ("GML3".equals(outputFormat)) {
+ encodeCollectionAsGML(res, out);
+ } else if ("application/json".equals(outputFormat)) {
+ encodeCollectionAsGeoJSon(res, out, typeNames);
+ }
+ }
+ }
+
+ /**
+ * Retrieve KVP (keyword-value pairs) parameters, which are lower case, as per
+ * specifications.
+ *
+ * @see https://docs.ogc.org/is/09-025r2/09-025r2.html#19
+ */
+ protected String getKvpParameter(Map<String, List<String>> parameters, WfsKvp key) {
+ Objects.requireNonNull(key, "KVP key cannot be null");
+ // let's first try the default (CAML case) which should be more efficient
+ List<String> values = parameters.get(key.getKey());
+ if (values == null) {
+ // then let's do an ignore case comparison of the key
+ keys: for (String k : parameters.keySet()) {
+ if (key.getKey().equalsIgnoreCase(k)) {
+ values = parameters.get(k);
+ break keys;
+ }
+ }
+ }
+ if (values == null) // nothing was found
+ return null;
+ if (values.size() != 1) {
+ // although not completely clear from the standard, we assume keys must be
+ // unique
+ // since lists are defined here
+ // https://docs.ogc.org/is/09-026r2/09-026r2.html#10
+ throw new IllegalArgumentException("Key " + key + " as multiple values");
+ }
+ String value = values.get(0);
+ assert value != null;
+ return value;
+ }
+
+ protected void encodeCollectionAsGeoJSon(Stream<Content> features, OutputStream out, List<QName> typeNames)
+ throws IOException {
+ long begin = System.currentTimeMillis();
+ AtomicLong count = new AtomicLong(0);
+ JsonGenerator generator = Json.createGenerator(out);
+ generator.writeStartObject();
+ generator.write("type", "FeatureCollection");
+ generator.writeStartArray("features");
+ features.forEach((c) -> {
+ // TODO deal with multiple type names
+ FeatureAdapter featureAdapter = null;
+ QName typeName = null;
+ if (!typeNames.isEmpty()) {
+ typeName = typeNames.get(0);
+ featureAdapter = featureAdapters.get(typeName);
+ }
+
+ boolean geometryWritten = false;
+// if (typeName.getLocalPart().equals("fieldSimpleFeature")) {
+// Content area = c.getContent("place.geom.json").orElse(null);
+// if (area != null) {
+// generator.writeStartObject();
+// generator.write("type", "Feature");
+// String featureId = getFeatureId(c);
+// if (featureId != null)
+// generator.write("id", featureId);
+//
+// generator.flush();
+// try (InputStream in = area.open(InputStream.class)) {
+// out.write(",\"geometry\":".getBytes());
+// StreamUtils.copy(in, out);
+// //out.flush();
+// } catch (Exception e) {
+// log.error(c.getPath() + " : " + e.getMessage());
+// } finally {
+// }
+// geometryWritten = true;
+// }else {
+// return;
+// }
+// }
+
+ if (!geometryWritten) {
+
+ Geometry defaultGeometry = featureAdapter != null ? featureAdapter.getDefaultGeometry(c, typeName)
+ : getDefaultGeometry(c);
+ if (defaultGeometry == null)
+ return;
+ generator.writeStartObject();
+ generator.write("type", "Feature");
+ String featureId = getFeatureId(c);
+ if (featureId != null)
+ generator.write("id", featureId);
+
+ GeoJson.writeBBox(generator, defaultGeometry);
+ generator.writeStartObject(GeoJson.GEOMETRY);
+ GeoJson.writeGeometry(generator, defaultGeometry);
+ generator.writeEnd();// geometry object
+ }
+ generator.writeStartObject(GeoJson.PROPERTIES);
+ AcrJsonUtils.writeTimeProperties(generator, c);
+ if (featureAdapter != null)
+ featureAdapter.writeProperties(generator, c, typeName);
+ else
+ writeProperties(generator, c);
+ generator.writeEnd();// properties object
+
+ generator.writeEnd();// feature object
+
+ if (count.incrementAndGet() % 10 == 0)
+ try {
+ out.flush();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ });
+ generator.writeEnd();// features array
+ generator.writeEnd().close();
+
+ log.debug("GeoJSon encoding took " + (System.currentTimeMillis() - begin) + " ms.");
+ }
+
+ protected Geometry getDefaultGeometry(Content content) {
+ if (content.hasContentClass(EntityType.geopoint)) {
+ return GeoEntityUtils.toPoint(content);
+ }
+ return null;
+ }
+
+ protected String getFeatureId(Content content) {
+ String uuid = content.attr(LdapAttr.entryUUID);
+ return uuid;
+ }
+
+ public void writeProperties(JsonGenerator generator, Content content) {
+ String path = content.getPath();
+ generator.write("path", path);
+ if (content.hasContentClass(EntityType.local)) {
+ String type = content.attr(EntityName.type);
+ generator.write("type", type);
+ } else {
+ List<QName> contentClasses = content.getContentClasses();
+ if (!contentClasses.isEmpty()) {
+ generator.write("type", NamespaceUtils.toPrefixedName(contentClasses.get(0)));
+ }
+ }
+
+ }
+
+ protected void encodeCollectionAsGML(Stream<Content> features, OutputStream out) throws IOException {
+ String entityType = "entity";
+ URL schemaLocation = getClass().getResource("/org/argeo/app/api/entity.xsd");
+ String namespace = "http://www.argeo.org/ns/entity";
+
+ GML gml = new GML(Version.WFS1_1);
+ gml.setCoordinateReferenceSystem(DefaultGeographicCRS.WGS84);
+ gml.setNamespace("local", namespace);
+
+ SimpleFeatureType featureType = gml.decodeSimpleFeatureType(schemaLocation,
+ new NameImpl(namespace, entityType + "Feature"));
+
+// CoordinateReferenceSystem crs=DefaultGeographicCRS.WGS84;
+// QName featureName = new QName(namespace,"apafFieldFeature");
+// GMLConfiguration configuration = new GMLConfiguration();
+// FeatureType parsed = GTXML.parseFeatureType(configuration, featureName, crs);
+// SimpleFeatureType featureType = DataUtilities.simple(parsed);
+
+ SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
+
+ DefaultFeatureCollection featureCollection = new DefaultFeatureCollection();
+
+ features.forEach((c) -> {
+// boolean gpx = false;
+ Geometry the_geom = null;
+ Polygon the_area = null;
+// if (gpx) {
+ Content area = c.getContent("gpx/area.gpx").orElse(null);
+ if (area != null) {
+
+ try (InputStream in = area.open(InputStream.class)) {
+ the_area = GpxUtils.parseGpxTrackTo(in, Polygon.class);
+ } catch (IOException e) {
+ throw new UncheckedIOException("Cannot parse " + c, e);
+ }
+ }
+// } else {
+ if (c.hasContentClass(EntityType.geopoint)) {
+ double latitude = c.get(WGS84PosName.lat, Double.class).get();
+ double longitude = c.get(WGS84PosName.lon, Double.class).get();
+
+ Coordinate coordinate = new Coordinate(longitude, latitude);
+ the_geom = JTS.GEOMETRY_FACTORY.createPoint(coordinate);
+ }
+
+// }
+ if (the_geom != null)
+ featureBuilder.set(new NameImpl(namespace, "geopoint"), the_geom);
+ if (the_area != null)
+ featureBuilder.set(new NameImpl(namespace, "area"), the_area);
+
+ List<AttributeDescriptor> attrDescs = featureType.getAttributeDescriptors();
+ for (AttributeDescriptor attrDesc : attrDescs) {
+ if (attrDesc instanceof GeometryAttribute)
+ continue;
+ Name name = attrDesc.getName();
+ QName qName = new QName(name.getNamespaceURI(), name.getLocalPart());
+ String value = c.attr(qName);
+ if (value == null) {
+ value = c.attr(name.getLocalPart());
+ }
+ if (value != null) {
+ featureBuilder.set(name, value);
+ }
+ }
+
+ String uuid = c.attr(LdapAttr.entryUUID);
+
+ SimpleFeature feature = featureBuilder.buildFeature(uuid);
+ featureCollection.add(feature);
+
+ });
+ gml.encode(out, featureCollection);
+ out.close();
+
+ }
+
+ /*
+ * DEPENDENCY INJECTION
+ */
+
+ public void addFeatureAdapter(FeatureAdapter featureAdapter, Map<String, Object> properties) {
+ List<String> typeNames = LangUtils.toStringList(properties.get(WfsKvp.TYPE_NAMES.getKey()));
+ if (typeNames.isEmpty()) {
+ log.warn("FeatureAdapter " + featureAdapter.getClass() + " does not declare type names. Ignoring it...");
+ return;
+ }
+
+ for (String tn : typeNames) {
+ QName typeName = NamespaceUtils.parsePrefixedName(tn);
+ featureAdapters.put(typeName, featureAdapter);
+ }
+ }
+
+ public void removeFeatureAdapter(FeatureAdapter featureAdapter, Map<String, Object> properties) {
+ List<String> typeNames = LangUtils.toStringList(properties.get(WfsKvp.TYPE_NAMES.getKey()));
+ if (!typeNames.isEmpty()) {
+ // ignore if noe type name declared
+ return;
+ }
+
+ for (String tn : typeNames) {
+ QName typeName = NamespaceUtils.parsePrefixedName(tn);
+ featureAdapters.remove(typeName);
+ }
+ }
+
+ public void setContentRepository(ProvidedRepository contentRepository) {
+ this.contentRepository = contentRepository;
+ }
+}
--- /dev/null
+package org.argeo.app.geo.http;
+
+import javax.xml.namespace.NamespaceContext;
+
+/** Utilities around the WFS specifications. */
+public class WfsUtils {
+
+ public static NamespaceContext parseNamespacesKvpParameter() {
+ // TODO deal with multiple namespaces
+ return null;
+ }
+
+ /** singleton */
+ private WfsUtils() {
+ }
+}
--- /dev/null
+package org.argeo.app.geo.ux;
+
+import org.argeo.app.ux.js.AbstractJsObject;
+
+public class AbstractGeoJsObject extends AbstractJsObject {
+ public final static String ARGEO_APP_GEO_JS_URL = "/pkg/org.argeo.app.js/geo.html";
+ public final static String JS_PACKAGE = "argeo.app.geo";
+
+ public AbstractGeoJsObject(Object... args) {
+ super(args);
+ }
+
+ @Override
+ public String getJsPackage() {
+ return JS_PACKAGE;
+ }
+}
--- /dev/null
+package org.argeo.app.geo.ux;
+
+import org.argeo.app.ol.FeatureFormat;
+import org.argeo.app.ol.VectorSource;
+
+public class BboxVectorSource extends VectorSource {
+
+ public BboxVectorSource(Object... args) {
+ super(args);
+ }
+
+ public BboxVectorSource(String baseUrl, FeatureFormat format) {
+ setFormat(format);
+ setBaseUrl(baseUrl);
+ }
+
+ @Override
+ public String getJsPackage() {
+ return AbstractGeoJsObject.JS_PACKAGE;
+ }
+
+ public void setBaseUrl(String baseUrl) {
+ doSetValue(null, "baseUrl", baseUrl);
+ }
+
+}
--- /dev/null
+package org.argeo.app.geo.ux;
+
+/** An UX part displaying a map. */
+public interface MapPart {
+ void setCenter(double lng, double lat);
+
+ /** Event when a feature has been single-clicked. */
+ record FeatureSingleClickEvent(String path) {
+ };
+
+ /** Event when a feature has been selected. */
+ record FeatureSelectedEvent(String path) {
+ };
+
+ /** Event when a feature popup is requested. */
+ record FeaturePopupEvent(String path) {
+ };
+}
--- /dev/null
+package org.argeo.app.geo.ux;
+
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.argeo.app.ol.AbstractOlObject;
+import org.argeo.app.ol.Layer;
+import org.argeo.app.ol.OlMap;
+import org.argeo.app.ol.TileLayer;
+import org.argeo.app.ol.VectorLayer;
+import org.argeo.app.ux.js.JsClient;
+import org.locationtech.jts.geom.Envelope;
+
+/**
+ * A wrapper around an OpenLayers map, adding specific features, such as SLD
+ * styling.
+ */
+public class OpenLayersMapPart extends AbstractGeoJsObject implements MapPart {
+ private final String mapPartName;
+
+ public OpenLayersMapPart(JsClient jsClient, String mapPartName) {
+ super(mapPartName);
+ this.mapPartName = mapPartName;
+ create(jsClient, mapPartName);
+ }
+
+ public OlMap getMap() {
+ return new OlMap(getJsClient(), getReference() + ".getMap()");
+ }
+
+ public void setSld(String xml) {
+ executeMethod(getMethodName(), JsClient.escapeQuotes(xml));
+ }
+
+ public void setCenter(double lat, double lon) {
+ executeMethod(getMethodName(), lat, lon);
+ }
+
+ public void fit(double[] extent, Map<String, Object> options) {
+ executeMethod(getMethodName(), extent, options);
+ }
+
+ public void fit(Envelope extent, Map<String, Object> options) {
+ fit(new double[] { extent.getMinX(), extent.getMinY(), extent.getMaxX(), extent.getMaxY() }, options);
+ }
+
+ public void applyStyle(String layerName, String styledLayerName) {
+ executeMethod(getMethodName(), layerName, styledLayerName);
+ }
+
+ public Layer getLayer(String name) {
+ // TODO deal with not found
+ String reference = getReference() + ".getLayerByName('" + name + "')";
+ if (getJsClient().isInstanceOf(reference, AbstractOlObject.getJsClassName(VectorLayer.class))) {
+ return new VectorLayer(getJsClient(), reference);
+ } else if (getJsClient().isInstanceOf(reference, AbstractOlObject.getJsClassName(TileLayer.class))) {
+ return new TileLayer(getJsClient(), reference);
+ } else {
+ return new Layer(getJsClient(), reference);
+ }
+ }
+
+ public String getMapPartName() {
+ return mapPartName;
+ }
+
+ public void selectFeatures(String layerName, Object... ids) {
+ executeMethod(getMethodName(), layerName, (Object[]) ids);
+ }
+
+ public void fitToLayer(String layerName) {
+ executeMethod(getMethodName(), layerName);
+ }
+
+ /*
+ * CALLBACKS
+ */
+ public void onFeatureSelected(Consumer<FeatureSelectedEvent> toDo) {
+ addCallback("FeatureSelected", (arr) -> {
+ toDo.accept(new FeatureSelectedEvent((String) arr[0]));
+ return null;
+ });
+ }
+
+ public void onFeatureSingleClick(Consumer<FeatureSingleClickEvent> toDo) {
+ addCallback("FeatureSingleClick", (arr) -> {
+ toDo.accept(new FeatureSingleClickEvent((String) arr[0]));
+ return null;
+ });
+ }
+
+ public void onFeaturePopup(Function<FeaturePopupEvent, String> toDo) {
+ addCallback("FeaturePopup", (arr) -> {
+ return toDo.apply(new FeaturePopupEvent((String) arr[0]));
+ });
+ }
+
+ protected void addCallback(String suffix, Function<Object[], Object> toDo) {
+ getJsClient().getReadyStage().thenAccept((ready) -> {
+ String functionName = getJsClient().createJsFunction(getMapPartName() + "__on" + suffix, toDo);
+ getJsClient().execute(getJsReference() + ".callbacks['on" + suffix + "']=" + functionName + ";");
+ executeMethod("enable" + suffix);
+ });
+ }
+
+}
--- /dev/null
+package org.argeo.app.geo.ux;
+
+import org.argeo.app.ol.Source;
+
+public class SentinelCloudless extends Source {
+
+ public SentinelCloudless(Object... args) {
+ super(args);
+ }
+
+ @Override
+ public String getJsPackage() {
+ return "argeo.app.geo";
+ }
+
+}
--- /dev/null
+package org.argeo.app.ol;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import org.argeo.app.ux.js.AbstractJsObject;
+
+public abstract class AbstractOlObject extends AbstractJsObject {
+ public final static String JS_PACKAGE = "argeo.tp.ol";
+
+ public AbstractOlObject(Object... args) {
+ super(args.length > 0 ? args : new Object[] { new HashMap<String, Object>() });
+ }
+
+// public AbstractOlObject(Map<String, Object> options) {
+// super(new Object[] { options });
+// }
+
+ public String getJsPackage() {
+ return JS_PACKAGE;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Map<String, Object> getNewOptions() {
+ if (!isNew())
+ throw new IllegalStateException("Object " + getJsClassName() + " is not new");
+ Object[] args = getJsConstructorArgs();
+ if (args.length != 1 || !(args[0] instanceof Map))
+ throw new IllegalStateException("Object " + getJsClassName() + " has no available options");
+ return (Map<String, Object>) args[0];
+ }
+
+ protected void doSetValue(String methodName, String newOption, Object value) {
+ if (isNew()) {
+ Objects.requireNonNull(newOption, "Value cannot be set as an option for " + getJsClassName() + ", use "
+ + methodName + "() after the object has been created");
+ getNewOptions().put(newOption, value);
+ } else {
+ Objects.requireNonNull(methodName, "Value cannot be set via a method for " + getJsClassName() + ", use "
+ + newOption + " before the object is created");
+ executeMethod(methodName, value);
+ }
+ }
+
+ public void set(String key, Object value) {
+ set(key, value, false);
+ }
+
+ public void set(String key, Object value, boolean silent) {
+ if (isNew()) {
+ getNewOptions().put(key, value);
+ } else {
+ executeMethod(getMethodName(), new Object[] { key, value, silent });
+ }
+ }
+
+ public Object get(String key) {
+ if (isNew()) {
+ return getNewOptions().get(key);
+ } else {
+ // TDO deal with reference if we are trying to get an object
+ return callMethod(getMethodName(), key);
+ }
+
+ }
+
+ public static String getJsClassName(Class<?> clss) {
+ if (AbstractOlObject.class.isAssignableFrom(clss)) {
+ // NB: would failed for renamed classes
+ return JS_PACKAGE + "." + clss.getSimpleName();
+ }
+ throw new IllegalArgumentException(clss + " is not an OpenLayers object");
+ }
+
+}
--- /dev/null
+package org.argeo.app.ol;
+
+public abstract class FeatureFormat extends AbstractOlObject {
+
+ public FeatureFormat(Object... args) {
+ super(args);
+ }
+
+}
--- /dev/null
+package org.argeo.app.ol;
+
+public class GeoJSON extends FeatureFormat {
+
+ public GeoJSON(Object... args) {
+ super(args);
+ }
+
+}
--- /dev/null
+package org.argeo.app.ol;
+
+import java.util.Objects;
+
+public class Layer extends AbstractOlObject {
+ public final static String NAME_KEY = "name";
+
+ // cached
+ private String name;
+
+ public Layer(Object... args) {
+ super(args);
+ }
+
+ public void setOpacity(double opacity) {
+ if (opacity < 0 || opacity > 1)
+ throw new IllegalArgumentException("Opacity must be between 0 and 1");
+// if (isNew())
+// getNewOptions().put("opacity", opacity);
+// else
+// executeMethod(getMethodName(), opacity);
+ doSetValue(getMethodName(), "opacity", opacity);
+ }
+
+ public void setSource(Source source) {
+ Objects.requireNonNull(source);
+ if (isNew())
+ getNewOptions().put("source", source);
+ else
+ executeMethod(getMethodName(), source);
+ }
+
+ public Source getSource() {
+ String reference = getReference() + ".getSource()";
+ return new Source(getJsClient(), reference);
+ }
+
+ public void setMinResolution(double minResolution) {
+ if (isNew())
+ getNewOptions().put("minResolution", minResolution);
+ else
+ executeMethod(getMethodName(), minResolution);
+ }
+
+ public void setMaxResolution(double maxResolution) {
+ if (isNew())
+ getNewOptions().put("maxResolution", maxResolution);
+ else
+ executeMethod(getMethodName(), maxResolution);
+ }
+
+ public void setName(String name) {
+ set(NAME_KEY, name);
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
--- /dev/null
+package org.argeo.app.ol;
+
+public class OSM extends Source {
+
+ public OSM(Object... args) {
+ super(args);
+ }
+
+}
--- /dev/null
+package org.argeo.app.ol;
+
+public class OlMap extends AbstractOlObject {
+
+ public OlMap(Object... args) {
+ super(args);
+ }
+
+ public void addLayer(Layer layer) {
+ executeMethod(getMethodName(), layer);
+ }
+
+ public View getView() {
+ return new View(getJsClient(), getReference() + ".getView()");
+ }
+
+ @Override
+ public String getJsClassName() {
+ return getJsPackage() + ".Map";
+ }
+
+}
--- /dev/null
+package org.argeo.app.ol;
+
+public class Source extends AbstractOlObject {
+
+ public Source(Object... args) {
+ super(args);
+ }
+
+ public void refresh() {
+ executeMethod(getMethodName());
+ }
+}
--- /dev/null
+package org.argeo.app.ol;
+
+public class TileLayer extends Layer {
+ public TileLayer(Object... args) {
+ super(args);
+ }
+
+ public TileLayer(Source source) {
+ setSource(source);
+ }
+}
--- /dev/null
+package org.argeo.app.ol;
+
+public class VectorLayer extends Layer {
+ public VectorLayer(Object... args) {
+ super(args);
+ }
+
+ public VectorLayer(String name, Source source) {
+ this(source);
+ setName(name);
+ }
+
+ public VectorLayer(Source source) {
+ setSource(source);
+ }
+}
--- /dev/null
+package org.argeo.app.ol;
+
+public class VectorSource extends Source {
+
+ public VectorSource(Object... args) {
+ super(args);
+ }
+
+ public VectorSource(String url, FeatureFormat format) {
+ setUrl(url);
+ setFormat(format);
+ }
+
+ public void setUrl(String url) {
+ doSetValue(getMethodName(), "url", url);
+ }
+
+ public void setFormat(FeatureFormat format) {
+ doSetValue(null, "format", format);
+ }
+}
--- /dev/null
+package org.argeo.app.ol;
+
+public class View extends AbstractOlObject {
+ public View(Object... args) {
+ super(args);
+ }
+
+ public void setCenter(int[] coord) {
+ if (isNew())
+ getNewOptions().put("center", coord);
+ else
+ executeMethod(getMethodName(), new Object[] { coord });
+ }
+
+ public void setZoom(int zoom) {
+ if (isNew())
+ getNewOptions().put("zoom", zoom);
+ else
+ executeMethod(getMethodName(), zoom);
+ }
+
+// public void fit(double[] extent) {
+// executeMethod(getMethodName(), extent);
+// }
+// public void setProjection(String projection) {
+// doSetValue(getMethodName(), "projection", projection);
+// }
+}
import java.util.Map;
-import javax.jcr.Node;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.osgi.framework.BundleContext;
/** An entity definition based on a JCR data structure. */
+@Deprecated
public class JcrEntityDefinition implements EntityDefinition {
private Repository repository;
private String type;
- private String defaultEditorId;
+// private String defaultEditorId;
public void init(BundleContext bundleContext, Map<String, String> properties) throws RepositoryException {
Session adminSession = CmsJcrUtils.openDataAdminSession(repository, null);
type = properties.get(EntityConstants.TYPE);
if (type == null)
throw new IllegalArgumentException("Entity type property " + EntityConstants.TYPE + " must be set.");
- defaultEditorId = properties.get(EntityConstants.DEFAULT_EDITOR_ID);
+// defaultEditorId = properties.get(EntityConstants.DEFAULT_EDITOR_ID);
// String definitionPath = EntityNames.ENTITY_DEFINITIONS_PATH + '/' + type;
// if (!adminSession.itemExists(definitionPath)) {
// Node entityDefinition = JcrUtils.mkdirs(adminSession, definitionPath, EntityTypes.ENTITY_DEFINITION);
}
- @Override
- public String getEditorId(Node entity) {
- return defaultEditorId;
- }
+// @Override
+// public String getEditorId(Node entity) {
+// return defaultEditorId;
+// }
@Override
public String getType() {
import org.apache.commons.io.output.NullOutputStream;
import org.argeo.app.api.EntityMimeType;
+import org.argeo.app.api.EntityType;
+import org.argeo.app.api.WGS84PosName;
+import org.argeo.app.geo.GeoShapeUtils;
import org.argeo.app.odk.OrxManifestName;
import org.argeo.cms.auth.RemoteAuthUtils;
import org.argeo.cms.servlet.ServletHttpRequest;
}
// TODO make it more configurable
columnNames.add("display");
+ columnNames.add("geometry");
if (EntityMimeType.XML.equals(mimeType)) {
} else if (EntityMimeType.CSV.equals(mimeType)) {
}
// display
lst.add(row.getValue("name").getString() + " (" + row.getValue("label").getString() + ")");
+ Node field = row.getNode("geopoint");
+ if (field != null && field.isNodeType(EntityType.geopoint.get())) {
+ double lat = field.getProperty(WGS84PosName.lat.get()).getDouble();
+ double lon = field.getProperty(WGS84PosName.lon.get()).getDouble();
+ double alt = field.hasProperty(WGS84PosName.alt.get())
+ ? field.getProperty(WGS84PosName.alt.get()).getDouble()
+ : Double.NaN;
+ String geoshape = GeoShapeUtils.geoPointToGeoShape(lon, lat, alt);
+ lst.add(geoshape);
+ }
csvWriter.writeLine(lst);
}
} else {
private final static CmsLog log = CmsLog.getLog(OdkSubmissionServlet.class);
private final static String XML_SUBMISSION_FILE = "xml_submission_file";
+ private final static String IS_INCOMPLETE = "*isIncomplete*";
private DateTimeFormatter submissionNameFormatter = DateTimeFormatter.ofPattern("YYYY-MM-dd-HHmmssSSS")
.withZone(ZoneId.from(ZoneOffset.UTC));
-// private Repository repository;
-// private ContentRepository contentRepository;
-
private Set<FormSubmissionListener> submissionListeners = new HashSet<>();
private AppUserState appUserState;
resp.setHeader("X-OpenRosa-Version", "1.0");
resp.setDateHeader("Date", System.currentTimeMillis());
- // should be set in HEAD? Let's rather use defaults.
- // resp.setIntHeader("X-OpenRosa-Accept-Content-Length", 1024 * 1024);
-
RemoteAuthRequest request = new ServletHttpRequest(req);
-// Session session = RemoteAuthUtils.doAs(() -> Jcr.login(repository, null), request);
-//
CmsSession cmsSession = RemoteAuthUtils.getCmsSession(request);
-// Session adminSession = null;
-// try {
-// // TODO centralise at a deeper level
-// adminSession = CmsJcrUtils.openDataAdminSession(repository, null);
-// SuiteJcrUtils.getOrCreateCmsSessionNode(adminSession, cmsSession);
-// } finally {
-// Jcr.logout(adminSession);
-// }
-
+ boolean isIncomplete = false;
try {
Content sessionDir = appUserState.getOrCreateSessionDir(cmsSession);
Node cmsSessionNode = sessionDir.adapt(Node.class);
- // Node cmsSessionNode = SuiteJcrUtils.getCmsSessionNode(session, cmsSession);
- Node submission = cmsSessionNode.addNode(submissionNameFormatter.format(Instant.now()),
- OrxType.submission.get());
+ String submissionName = submissionNameFormatter.format(Instant.now());
+ Node submission = cmsSessionNode.addNode(submissionName, OrxType.submission.get());
+ String submissionPath = submission.getPath();
for (Part part : req.getParts()) {
+ String partNameSane = JcrUtils.replaceInvalidChars(part.getName());
if (log.isTraceEnabled())
log.trace("Part: " + part.getName() + ", " + part.getContentType());
cmsSessionNode.getSession().importXML(xml.getPath(), part.getInputStream(),
ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
+ } else if (part.getName().equals(IS_INCOMPLETE)) {
+ isIncomplete = true;
+ log.debug("Form submission " + submissionPath + " is incomplete, expecting more to be uploaded...");
} else {
Node fileNode;
if (part.getName().endsWith(".jpg")) {
ImageProcessor imageProcessor = new ImageProcessor(() -> part.getInputStream(),
() -> Files.newOutputStream(temp));
imageProcessor.process();
- fileNode = JcrUtils.copyStreamAsFile(submission, part.getName(),
- Files.newInputStream(temp));
+ fileNode = JcrUtils.copyStreamAsFile(submission, partNameSane, Files.newInputStream(temp));
} finally {
Files.deleteIfExists(temp);
}
} else {
- fileNode = JcrUtils.copyStreamAsFile(submission, part.getName(), part.getInputStream());
+ fileNode = JcrUtils.copyStreamAsFile(submission, partNameSane, part.getInputStream());
}
String contentType = part.getContentType();
if (contentType != null) {
fileNode.addMixin(NodeType.MIX_MIMETYPE);
fileNode.setProperty(Property.JCR_MIMETYPE, contentType);
-
}
if (part.getName().endsWith(".jpg") || part.getName().endsWith(".png")) {
// TODO meta data and thumbnails
cmsSessionNode.getSession().save();
try {
for (FormSubmissionListener submissionListener : submissionListeners) {
- submissionListener.formSubmissionReceived(JcrContent.nodeToContent(submission));
+ submissionListener.formSubmissionReceived(JcrContent.nodeToContent(submission), isIncomplete);
}
} catch (Exception e) {
- log.error("Cannot save submision, cancelling...", e);
- submission.remove();
+ log.error("Cannot save submission, cancelling...", e);
+ if (cmsSessionNode.getSession().hasPendingChanges())
+ cmsSessionNode.getSession().refresh(false);// discard
+ if (cmsSessionNode.getSession().itemExists(submissionPath))
+ submission.remove();
cmsSessionNode.getSession().save();
resp.setStatus(503);
return;
}
} catch (Exception e) {
- log.error("Cannot save submision", e);
+ log.error("Cannot save submission", e);
resp.setStatus(503);
return;
-// } finally {
-// Jcr.logout(session);
}
resp.setStatus(201);
}
-// public void setRepository(Repository repository) {
-// this.repository = repository;
-// }
-
public synchronized void addSubmissionListener(FormSubmissionListener listener) {
submissionListeners.add(listener);
}
submissionListeners.remove(listener);
}
-// public void setContentRepository(ContentRepository contentRepository) {
-// this.contentRepository = contentRepository;
-// }
-
public void setAppUserState(AppUserState appUserState) {
this.appUserState = appUserState;
}
import org.argeo.api.acr.Content;
import org.argeo.api.acr.ContentRepository;
import org.argeo.api.acr.ContentSession;
+import org.argeo.api.acr.NamespaceUtils;
import org.argeo.app.geo.GeoUtils;
import org.argeo.app.geo.GpxUtils;
+import org.argeo.app.geo.acr.GeoEntityUtils;
import org.argeo.cms.acr.xml.XmlNormalizer;
import org.argeo.cms.auth.RemoteAuthUtils;
import org.argeo.cms.servlet.ServletHttpRequest;
import org.argeo.cms.util.LangUtils;
-import org.geotools.data.collection.ListFeatureCollection;
-import org.geotools.data.simple.SimpleFeatureCollection;
-import org.opengis.feature.simple.SimpleFeature;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.Polygon;
import net.sf.saxon.BasicTransformerFactory;
return new StreamSource(in);
}
if (url.getScheme().equals("geo2svg")) {
- String includePath = path + url.getPath();
- String geoExt = includePath.substring(includePath.lastIndexOf('.'));
- Content geoContent = session.get(includePath);
- if (".gpx".equals(geoExt)) {
- try (InputStream in = geoContent.open(InputStream.class)) {
- SimpleFeature field = GpxUtils.parseGpxToPolygon(in);
- SimpleFeatureCollection features = new ListFeatureCollection(field.getType(), field);
- try (StringWriter writer = new StringWriter()) {
- GeoUtils.exportToSvg(features, writer, 100, 100);
- StreamSource res = new StreamSource(new StringReader(writer.toString()));
- return res;
+ int lastDot = url.getPath().lastIndexOf('.');
+ Polygon polygon;
+ if (lastDot > 0) {
+ String includePath = path + url.getPath();
+ Content geoContent = session.get(includePath);
+ String geoExt = includePath.substring(lastDot);
+ if (".gpx".equals(geoExt)) {
+ try (InputStream in = geoContent.open(InputStream.class)) {
+ polygon = GpxUtils.parseGpxTrackTo(in, Polygon.class);
}
+ } else {
+ throw new UnsupportedOperationException(geoExt + " is not supported");
}
} else {
- throw new UnsupportedOperationException(geoExt + " is not supported");
+ Content geoContent;
+ String attrName;
+ if (url.getPath().startsWith("/@")) {
+ geoContent = content;
+ attrName = url.getPath().substring(2);// remove /@
+ } else {
+ throw new IllegalArgumentException("Only direct attributes are currently supported");
+ }
+ polygon = GeoEntityUtils.getGeometry(geoContent, NamespaceUtils.parsePrefixedName(attrName),
+ Polygon.class);
+ }
+ try (StringWriter writer = new StringWriter()) {
+ GeoUtils.exportToSvg(new Geometry[] { polygon }, writer, 100, 100);
+ StreamSource res = new StreamSource(new StringReader(writer.toString()));
+ return res;
}
}
}
+++ /dev/null
-package org.argeo.app.servlet.publish;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.argeo.api.acr.Content;
-import org.argeo.api.acr.ContentRepository;
-import org.argeo.api.acr.ContentSession;
-import org.argeo.app.geo.GeoUtils;
-import org.argeo.app.geo.GpxUtils;
-import org.argeo.cms.auth.RemoteAuthUtils;
-import org.argeo.cms.servlet.ServletHttpRequest;
-import org.geotools.data.collection.ListFeatureCollection;
-import org.geotools.data.simple.SimpleFeatureCollection;
-import org.opengis.feature.simple.SimpleFeature;
-
-/**
- * A servlet transforming an geographical data to SVG.
- */
-public class GeoToSvgServlet extends HttpServlet {
- private static final long serialVersionUID = -6346379324580671894L;
- private ContentRepository contentRepository;
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- String servletPath = req.getServletPath();
-
- servletPath = servletPath.substring(1, servletPath.lastIndexOf('.'));
- servletPath = servletPath.substring(servletPath.indexOf('/'), servletPath.length());
- String path = URLDecoder.decode(servletPath, StandardCharsets.UTF_8);
- String ext = servletPath.substring(path.lastIndexOf('.'));
-
- resp.setContentType("image/svg+xml");
-
- ContentSession session = RemoteAuthUtils.doAs(() -> contentRepository.get(), new ServletHttpRequest(req));
- Content content = session.get(path);
- if (".gpx".equals(ext)) {
- try (InputStream in = content.open(InputStream.class)) {
- SimpleFeature field = GpxUtils.parseGpxToPolygon(in);
-
- SimpleFeatureCollection features = new ListFeatureCollection(field.getType(), field);
- GeoUtils.exportToSvg(features, resp.getWriter(), 100, 100);
-// log.debug("SVG:\n" + writer.toString() + "\n");
- }
- }
- }
-
- public void start(Map<String, Object> properties) {
- }
-
- public void stop(Map<String, Object> properties) {
-
- }
-
- public void setContentRepository(ContentRepository contentRepository) {
- this.contentRepository = contentRepository;
- }
-
-}
-Subproject commit d9cae87d811258d5a13e43eea8492f3792377ce4
+Subproject commit d5943f556d6fba9db0dd63d4c4cfceef89e4888e
org.argeo.cms.swt.rcp,\
org.argeo.cms.ee,\
org.argeo.cms.lib.dbus,\
+org.argeo.cms.lib.equinox,\
+org.argeo.cms.lib.jetty,\
argeo.osgi.start.4=\
org.argeo.cms.jcr
argeo.osgi.start.5=\
org.argeo.app.profile.acr.fs,\
org.argeo.app.core,\
+org.argeo.app.jcr,\
org.argeo.app.ui,\
org.argeo.app.theme.default,\
+org.argeo.app.geo,\
# Local
# DON'T CHANGE BELOW
org.eclipse.equinox.http.jetty.autostart=false
org.osgi.framework.system.packages.extra=\
+sun.security.internal.spec,\
+sun.security.provider,\
com.sun.net.httpserver,\
com.sun.jndi.ldap,\
com.sun.jndi.ldap.sasl,\
major=2
minor=3
-micro=15
+micro=19
qualifier=
Bundle-Copyright= \
SPDX-License-Identifier= \
GPL-2.0-or-later \
-OR LicenseRef-argeo2-GPL-2.0-or-later-with-EPL-and-JCR-permissions
+OR LicenseRef-argeo2-GPL-2.0-or-later-with-EPL-and-Apache-and-JCR-permissions
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.app.geo.swt</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
--- /dev/null
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
+org.eclipse.jdt.core.compiler.compliance=17
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=17
--- /dev/null
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
--- /dev/null
+Import-Package:\
+org.eclipse.swt,\
+org.argeo.cms.acr,\
+*
+
+Provide-Capability:\
+cms.publish;pkg=org.argeo.app.geo.swt.openlayers;file="*.png,*.js,*.css"
--- /dev/null
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
--- /dev/null
+package org.argeo.app.geo.swt;
+
+import org.argeo.api.acr.Content;
+import org.argeo.app.geo.ux.AbstractGeoJsObject;
+import org.argeo.app.geo.ux.OpenLayersMapPart;
+import org.argeo.app.geo.ux.SentinelCloudless;
+import org.argeo.app.ol.GeoJSON;
+import org.argeo.app.ol.Layer;
+import org.argeo.app.ol.OSM;
+import org.argeo.app.ol.TileLayer;
+import org.argeo.app.ol.VectorLayer;
+import org.argeo.app.ol.VectorSource;
+import org.argeo.app.swt.js.SwtBrowserJsPart;
+import org.argeo.app.ux.js.JsClient;
+import org.argeo.cms.swt.acr.SwtUiProvider;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/** Create map parts. */
+public class MapUiProvider implements SwtUiProvider {
+
+ @Override
+ public Control createUiPart(Composite parent, Content context) {
+ JsClient jsClient = new SwtBrowserJsPart(parent, 0, AbstractGeoJsObject.ARGEO_APP_GEO_JS_URL);
+ OpenLayersMapPart mapPart = new OpenLayersMapPart(jsClient, "defaultOverviewMap");
+ mapPart.getMap().getView().setCenter(new int[] { 0, 0 });
+ mapPart.getMap().getView().setZoom(6);
+
+ Layer satelliteLayer = new TileLayer(new SentinelCloudless());
+ satelliteLayer.setMaxResolution(200);
+ mapPart.getMap().addLayer(satelliteLayer);
+
+ TileLayer baseLayer = new TileLayer();
+ baseLayer.setSource(new OSM());
+ baseLayer.setOpacity(0.5);
+ mapPart.getMap().addLayer(baseLayer);
+
+ Layer dataLayer = new VectorLayer(new VectorSource(
+ "https://openlayers.org/en/v4.6.5/examples/data/geojson/countries.geojson", new GeoJSON()));
+ mapPart.getMap().addLayer(dataLayer);
+
+// SwtJsMapPart map = new SwtJsMapPart("defaultOverviewMap", parent, 0);
+// map.setCenter(13.404954, 52.520008); // Berlin
+//// map.setCenter(-74.00597, 40.71427); // NYC
+//// map.addPoint(-74.00597, 40.71427, null);
+// map.setZoom(6);
+// // map.addUrlLayer("https://openlayers.org/en/v4.6.5/examples/data/geojson/countries.geojson",
+// // Format.GEOJSON);
+ return parent;
+ }
+
+}
--- /dev/null
+package org.argeo.app.swt.chart;
+
+import org.argeo.app.swt.js.SwtBrowserJsPart;
+import org.eclipse.swt.widgets.Composite;
+
+/** Base class for charts. */
+public abstract class AbstractJsChart extends SwtBrowserJsPart {
+ private String chartName;
+
+ protected abstract String getJsImplementation();
+
+ public AbstractJsChart(String chartName, Composite parent, int style) {
+ super(parent, style, "/pkg/org.argeo.app.js/chart.html");
+ this.chartName = chartName;
+ }
+
+ @Override
+ protected void init() {
+ // create chart
+ doExecute(getJsChartVar() + " = new " + getJsImplementation() + "('" + chartName + "');");
+ }
+
+ protected String getJsChartVar() {
+ return getJsVarName(chartName);
+ }
+
+ protected void executeChartMethod(String methodCall, Object... args) {
+ executeMethod(getJsChartVar(), methodCall, args);
+ }
+
+}
--- /dev/null
+package org.argeo.app.swt.chart;
+
+import java.io.StringWriter;
+
+import org.argeo.app.ux.js.JsClient;
+import org.eclipse.swt.widgets.Composite;
+
+import jakarta.json.Json;
+import jakarta.json.stream.JsonGenerator;
+
+public class SwtJsBarChart extends AbstractJsChart {
+
+ public SwtJsBarChart(String chartName, Composite parent, int style) {
+ super(chartName, parent, style);
+ }
+
+ @Override
+ protected String getJsImplementation() {
+ return "globalThis.argeo.app.chart.BarChart";
+ }
+
+ public void setLabels(String[] labels) {
+ executeChartMethod("setLabels(%s)", JsClient.toJsArray(labels));
+ }
+
+ public void addDataset(String label, int[] values) {
+ executeChartMethod("addDataset('%s', %s)", label, JsClient.toJsArray(values));
+ }
+
+ public void setData(String[] labels, String label, int[] values) {
+ executeChartMethod("setData(%s, '%s', %s)", JsClient.toJsArray(labels), label, JsClient.toJsArray(values));
+ }
+
+ public void setDatasets(String[] labels, String[] label, int[][] values) {
+ executeChartMethod("setDatasets(%s, %s)", JsClient.toJsArray(labels), toDatasets(label, values));
+ }
+
+ protected String toDatasets(String[] label, int[][] values) {
+ if (label.length != values.length)
+ throw new IllegalArgumentException("Arrays must have the same length");
+ StringWriter writer = new StringWriter();
+ JsonGenerator g = Json.createGenerator(writer);
+ g.writeStartArray();
+ for (int i = 0; i < label.length; i++) {
+ g.writeStartObject();
+ g.write("label", label[i]);
+ g.writeStartArray("data");
+ for (int j = 0; j < values[i].length; j++) {
+ g.write(values[i][j]);
+ }
+ g.writeEnd();// data array
+ g.writeEnd();// dataset
+ }
+ g.writeEnd();
+ g.close();
+ return writer.toString();
+ }
+
+ public void clearDatasets() {
+ executeChartMethod("clearDatasets()");
+ }
+}
--- /dev/null
+package org.argeo.app.swt.js;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.function.Function;
+
+import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.ux.CmsView;
+import org.argeo.app.ux.js.JsClient;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.BrowserFunction;
+import org.eclipse.swt.browser.ProgressEvent;
+import org.eclipse.swt.browser.ProgressListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * A part using a {@link Browser} and remote JavaScript components on the client
+ * side.
+ */
+public class SwtBrowserJsPart implements JsClient {
+ private final static CmsLog log = CmsLog.getLog(SwtBrowserJsPart.class);
+
+ private final static String GLOBAL_THIS_ = "globalThis.";
+
+ private final Browser browser;
+ private final CompletableFuture<Boolean> readyStage = new CompletableFuture<>();
+
+ /**
+ * Tasks that were requested before the context was ready. Typically
+ * configuration methods on the part while the user interfaces is being build.
+ */
+ private List<PreReadyToDo> preReadyToDos = new ArrayList<>();
+
+ public SwtBrowserJsPart(Composite parent, int style, String url) {
+ CmsView cmsView = CmsSwtUtils.getCmsView(parent);
+ this.browser = new Browser(parent, 0);
+ if (parent.getLayout() instanceof GridLayout)
+ browser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ // TODO other layouts
+
+ URI u = cmsView.toBackendUri(url);
+ browser.setUrl(u.toString());
+ browser.addProgressListener(new ProgressListener() {
+ static final long serialVersionUID = 1L;
+
+ @Override
+ public void completed(ProgressEvent event) {
+ try {
+ init();
+ loadExtensions();
+ // execute todos in order
+ for (PreReadyToDo toDo : preReadyToDos) {
+ toDo.run();
+ }
+ preReadyToDos.clear();
+ readyStage.complete(true);
+ } catch (Exception e) {
+ log.error("Cannot initialise " + url + " in browser", e);
+ readyStage.complete(false);
+ }
+ }
+
+ @Override
+ public void changed(ProgressEvent event) {
+ }
+ });
+ }
+
+ /*
+ * LIFECYCLE
+ */
+
+ /**
+ * Called when the page has been loaded, typically in order to initialise
+ * JavaScript objects. One MUST use {@link #doExecute(String, Object...)} in
+ * order to do so, since the context is not yet considered ready and calls to
+ * {@link #evaluate(String, Object...)} will block.
+ */
+ protected void init() {
+ }
+
+ /**
+ * To be overridden with calls to {@link #loadExtension(String)}.
+ */
+ protected void loadExtensions() {
+
+ }
+
+ protected void loadExtension(String url) {
+ URI u = CmsSwtUtils.getCmsView(getControl()).toBackendUri(url);
+ browser.evaluate(String.format(Locale.ROOT, "import('%s')", u.toString()));
+ }
+
+ public CompletionStage<Boolean> getReadyStage() {
+ return readyStage.minimalCompletionStage();
+ }
+
+ /*
+ * JAVASCRIPT ACCESS
+ */
+
+ @Override
+ public Object evaluate(String js, Object... args) {
+ assert browser.getDisplay().equals(Display.findDisplay(Thread.currentThread())) : "Not the proper UI thread.";
+ if (!readyStage.isDone())
+ throw new IllegalStateException("Methods returning a result can only be called after UI initialisation.");
+ if (browser.isDisposed())
+ return null;
+ Object result = browser.evaluate(String.format(Locale.ROOT, js, args));
+ return result;
+ }
+
+ @Override
+ public void execute(String js, Object... args) {
+ String jsToExecute = String.format(Locale.ROOT, js, args);
+ if (readyStage.isDone()) {
+ if (browser.isDisposed())
+ return;
+ boolean success = browser.execute(jsToExecute);
+ if (!success)
+ throw new RuntimeException("JavaScript execution failed.");
+ } else {
+ PreReadyToDo toDo = new PreReadyToDo(jsToExecute);
+ preReadyToDos.add(toDo);
+ }
+ }
+
+ @Override
+ public String createJsFunction(String name, Function<Object[], Object> toDo) {
+ // browser functions must be directly on window (RAP specific)
+ new BrowserFunction(browser, name) {
+
+ @Override
+ public Object function(Object[] arguments) {
+ Object result = toDo.apply(arguments);
+ return result;
+ }
+
+ };
+ return "window." + name;
+ }
+
+ /**
+ * Directly executes, even if {@link #getReadyStage()} is not completed. Except
+ * in initialisation, {@link #evaluate(String, Object...)} should be used
+ * instead.
+ */
+ protected void doExecute(String js, Object... args) {
+ if (browser.isDisposed())
+ return;
+ browser.execute(String.format(Locale.ROOT, js, args));
+ }
+
+ @Override
+ public String getJsVarName(String name) {
+ return GLOBAL_THIS_ + name;
+ }
+
+ class PreReadyToDo implements Runnable {
+ private String js;
+
+ public PreReadyToDo(String js) {
+ this.js = js;
+ }
+
+ @Override
+ public void run() {
+ if (browser.isDisposed())
+ return;
+ boolean success = browser.execute(js);
+ if (!success && log.isTraceEnabled())
+ log.error("Pre-ready JavaScript failed: " + js);
+ }
+ }
+
+ /*
+ * ACCESSORS
+ */
+
+ public Control getControl() {
+ return browser;
+ }
+
+}
import org.argeo.cms.util.LangUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
} else {
if (this.workArea != null) {
Composite area = new Composite(parent, SWT.NONE);
+ // we set fill layout by default but it can be overridden
+ area.setLayout(new FillLayout());
this.workArea.createUiPart(area, context);
return area;
}
import org.argeo.api.cms.ux.CmsStyle;
import org.argeo.app.ux.SuiteStyle;
import org.argeo.cms.Localized;
+import org.argeo.cms.acr.ContentUtils;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.swt.acr.Img;
import org.argeo.cms.swt.dialogs.CmsFeedback;
* CONTENT
*/
public static String toLink(Content content) {
- return content != null ? "#" + CmsSwtUtils.cleanPathForUrl(content.getPath()) : null;
+ return content != null ? "#" + ContentUtils.cleanPathForUrl(content.getPath()) : null;
}
public static Text addFormLine(Composite parent, Localized label, Content content, QNamed property,
Text txt = SuiteSwtUtils.addFormTextField(parent, text, null, 0);
if (cmsEditable != null && cmsEditable.isEditing()) {
txt.addModifyListener((e) -> {
- content.put(property, txt.getText());
+ content.put(property, txt.getText().trim());
});
} else {
txt.setEditable(false);
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+ <implementation class="org.argeo.app.geo.swt.MapUiProvider"/>
+ <properties entry="config/defaultMap.properties"/>
+ <service>
+ <provide interface="org.argeo.cms.swt.acr.SwtUiProvider"/>
+ </service>
+ <property name="service.ranking" type="Integer" value="-1000"/>
+</scr:component>
<provide interface="org.argeo.app.swt.ux.SwtAppLayer"/>
</service>
<property name="service.ranking" type="Integer" value="-1000"/>
- <reference bind="setWorkArea" cardinality="1..1" interface="org.argeo.cms.swt.acr.SwtUiProvider" name="CmsUiProvider" policy="dynamic" target="(service.pid=argeo.geo.ui.overviewMap)"/>
+ <reference bind="setWorkArea" cardinality="1..1" interface="org.argeo.cms.swt.acr.SwtUiProvider" name="CmsUiProvider" policy="dynamic" target="(service.pid=argeo.geo.ui.defaultMap)"/>
</scr:component>
OSGI-INF/fsEntryArea.xml,\
OSGI-INF/mapLayer.xml,\
OSGI-INF/overviewMap.xml,\
+OSGI-INF/defaultMap.xml,\
OSGI-INF/wwwLayer.xml,\
OSGI-INF/documentUiProvider.xml,\
OSGI-INF/publishEntryArea.xml,\
org.eclipse.jface.window,\
org.eclipse.jface.dialogs,\
org.eclipse.rap.rwt,\
+org.argeo.app.geo.swt,\
javax.servlet.*;version="[3,5)",\
javax.jcr.nodetype,\
*
--- /dev/null
+service.pid=argeo.geo.ui.defaultMap
import org.argeo.app.api.EntityType;
import org.argeo.app.swt.ux.SuiteSwtUtils;
import org.argeo.app.ux.SuiteUxEvent;
+import org.argeo.cms.acr.ContentUtils;
import org.argeo.cms.jcr.acr.JcrContent;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.swt.dialogs.LightweightDialog;
}
public static String toLink(Node node) {
- return node != null ? "#" + CmsSwtUtils.cleanPathForUrl(JcrContent.nodeToContent(node).getPath()) : null;
+ return node != null ? "#" + ContentUtils.cleanPathForUrl(JcrContent.nodeToContent(node).getPath()) : null;
}
public static Control addLink(Composite parent, String label, Node node, CmsStyle style)
+++ /dev/null
-package org.argeo.app.ui.openlayers;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-
-public class OLMap extends Composite {
- private Label div;
-
- public OLMap(Composite parent, int style) {
- super(parent, style);
- setLayout(CmsSwtUtils.noSpaceGridLayout());
- div = new Label(this, SWT.NONE);
- CmsSwtUtils.markup(div);
- CmsSwtUtils.disableMarkupValidation(div);
- div.setText("<div id='map'></div>");
- div.setLayoutData(CmsSwtUtils.fillAll());
- }
-
-}
import java.awt.image.BufferedImage;
import java.nio.file.Paths;
-import org.apache.pdfbox.pdmodel.PDDocument;
-import org.apache.pdfbox.rendering.PDFRenderer;
+//import org.apache.pdfbox.pdmodel.PDDocument;
+//import org.apache.pdfbox.rendering.PDFRenderer;
import org.argeo.eclipse.ui.specific.BufferedImageDisplay;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
public class PdfViewer {
public static void main(String[] args) throws Exception {
- PDDocument doc = PDDocument.load(Paths.get(args[0]).toFile());
- PDFRenderer renderer = new PDFRenderer(doc);
-
- BufferedImage image = renderer.renderImageWithDPI(0, 300);
-
- Display display = new Display();
- Shell shell = new Shell(display);
- shell.setLayout(new FillLayout());
-
- shell.setSize(200, 200);
-
- BufferedImageDisplay imageDisplay = new BufferedImageDisplay(shell, SWT.NONE);
- imageDisplay.setImage(image);
-
- shell.open();
- while (!shell.isDisposed()) {
- if (!display.readAndDispatch())
- display.sleep();
- }
- display.dispose();
+// PDDocument doc = PDDocument.load(Paths.get(args[0]).toFile());
+// PDFRenderer renderer = new PDFRenderer(doc);
+//
+// BufferedImage image = renderer.renderImageWithDPI(0, 300);
+//
+// Display display = new Display();
+// Shell shell = new Shell(display);
+// shell.setLayout(new FillLayout());
+//
+// shell.setSize(200, 200);
+//
+// BufferedImageDisplay imageDisplay = new BufferedImageDisplay(shell, SWT.NONE);
+// imageDisplay.setImage(image);
+//
+// shell.open();
+// while (!shell.isDisposed()) {
+// if (!display.readAndDispatch())
+// display.sleep();
+// }
+// display.dispose();
}
}